Anyone have an interesting or idiomatic usage of Struct?
Other than the obvious usage for on-the-fly attr reader/writer
objects, what else can you do with this?
One use case that came to mind was for managing CSV files (esp. w/
headers). You could create a Struct for the file, using the header
row from the file, passing a block to the new method to add a method
to initialize it based on an array (as returned from the csv reader).
Anyone have a cool usage?
Joe at CodeGear
On Feb 16, 2007, at 7:30 PM, Joe at CodeGear wrote:
One use case that came to mind was for managing CSV files (esp. w/
headers). You could create a Struct for the file, using the header
row from the file, passing a block to the new method to add a method
to initialize it based on an array (as returned from the csv reader).
I really like the way you think:
#!/usr/bin/env ruby -w
require “rubygems”
require “faster_csv”
require “pp”
Name = Struct.new(:first, :last)
names = [Name.new(“James”, “Gray”), Name.new(“Joe”)]
csv = FCSV.dump(names)
puts <<END_CSV
CSV
#{csv}
END_CSV
reloaded = FCSV.load(csv)
puts <<END_RUBY
Ruby
END_RUBY
pp reloaded
>> CSV
>> ===
>> class,Name
>> first=,last=
>> James,Gray
>> Joe,
>>
>> Ruby
>> ====
>> [#<struct Name first=“James”, last=“Gray”>,
>> #<struct Name first=“Joe”, last=nil>]
END
James Edward G. II
On 2/17/07, Joe at CodeGear [email protected] wrote:
Anyone have a cool usage?
Joe at CodeGear
I was naming regular expressions with it roughly like this
Fields=Struct.new(:a,:b,:c)
/(x*)(y*)(z*)/ === whatever
named= Fields.new( *Regexp.last_match.captures )
Cheers
Robert
At work I need to process different bits of information stored in csv
format. I use OpenStruct modified to create new propertied from
strings that I read from the file headers. I don’t have the code
here, but can get it if anyone is interested.
I find this method very useful as then I can work with the properties
I require, but the code doesn’t fall over when the format of the
files changes (not that that would happen without anyone telling me
first…
)
Cheers,
Dave
On Sun, Feb 18, 2007 at 12:00:15AM +0900, Phrogz wrote:
On Feb 17, 1:39 am, “Robert D.” [email protected] wrote:
I was naming regular expressions with it roughly like this
Fields=Struct.new(:a,:b,:c)
/(x*)(y*)(z*)/ === whatever
named= Fields.new( *Regexp.last_match.captures )
Ooh, that’s quite cool. Thanks for sharing that! 
That’s one way of doing it. There was a discussion not too long ago of
doing it with the MatchData itself. Something like (tested, works):
class MatchData
def name_captures(*names)
meta = (class << self; self; end)
names.each_with_index { |name,index|
meta.send(:define_method, name) { captures[index] }
}
self
end
end
named = /(x*)(y*)(z*)/.match(whatever).name_captures(:a, :b, :c)
–Greg
On Feb 17, 1:39 am, “Robert D.” [email protected] wrote:
I was naming regular expressions with it roughly like this
Fields=Struct.new(:a,:b,:c)
/(x*)(y*)(z*)/ === whatever
named= Fields.new( *Regexp.last_match.captures )
Ooh, that’s quite cool. Thanks for sharing that! 
On 2/17/07, Gregory S. [email protected] wrote:
That’s one way of doing it. There was a discussion not too long ago of
end
named = /(x*)(y*)(z*)/.match(whatever).name_captures(:a, :b, :c)
–Greg
That seems a little bit heavy. I was thinking to extend
RegularExpressions so that the names could be bound to the Regexp for
one and than just thought that I do not have enough usecases.
AFAIK Ruby 2 will have named captures and I am not really smart enough
to handle
alternatives and nesting so I let it be…
Cheers
Robert
On 2/17/07, Phrogz [email protected] wrote:
My pleasure 
Robert