[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

interesting usages of Struct?

Joe at CodeGear

2/17/2007 1:26:00 AM

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

7 Answers

James Gray

2/17/2007 3:00:00 AM

0

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 Gray II




Robert Dober

2/17/2007 8:39:00 AM

0

On 2/17/07, Joe at CodeGear <jmcglynn@codegear.com> wrote:
> 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
>
>
>
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

--
We have not succeeded in answering all of our questions.
In fact, in some ways, we are more confused than ever.
But we feel we are confused on a higher level and about more important things.
-Anonymous

David and Sharon Phillips

2/17/2007 9:50:00 AM

0

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 17/02/2007, at 12:30 PM, Joe at CodeGear wrote:

> 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
>
>


Gavin Kistner

2/17/2007 2:56:00 PM

0

On Feb 17, 1:39 am, "Robert Dober" <robert.do...@gmail.com> 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! :)

Gregory Seidman

2/17/2007 3:18:00 PM

0

On Sun, Feb 18, 2007 at 12:00:15AM +0900, Phrogz wrote:
> On Feb 17, 1:39 am, "Robert Dober" <robert.do...@gmail.com> 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


Robert Dober

2/17/2007 11:31:00 PM

0

On 2/17/07, Phrogz <gavin@refinery.com> wrote:
> On Feb 17, 1:39 am, "Robert Dober" <robert.do...@gmail.com> 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! :)
>
>
>
My pleasure :)
Robert

Robert Dober

2/17/2007 11:37:00 PM

0

On 2/17/07, Gregory Seidman <gsslist+ruby@anthropohedron.net> wrote:
> On Sun, Feb 18, 2007 at 12:00:15AM +0900, Phrogz wrote:
> > On Feb 17, 1:39 am, "Robert Dober" <robert.do...@gmail.com> 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
>
>
>
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


--
We have not succeeded in answering all of our questions.
In fact, in some ways, we are more confused than ever.
But we feel we are confused on a higher level and about more important things.
-Anonymous