# Interesting usages of Struct?

**URL:** <https://www.ruby-forum.com/t/interesting-usages-of-struct/85876>\
**Category:** Ruby\
**Created:** [February 17, 2007, 2:30am UTC](https://www.ruby-forum.com/t/interesting-usages-of-struct/85876 "2007-02-17T02:30:36Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Joe\_at\_CodeGear](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/dec6dc/32.png) [@Joe\_at\_CodeGear](https://www.ruby-forum.com/u/Joe_at_CodeGear)\
**Post date:** [February 17, 2007, 2:30am UTC](https://www.ruby-forum.com/t/interesting-usages-of-struct/85876/1 "2007-02-17T02:30:36Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Joe\_at\_CodeGear](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/dec6dc/32.png) [@Joe\_at\_CodeGear](https://www.ruby-forum.com/u/Joe_at_CodeGear)\
**Post date:** [February 17, 2007, 4:00am UTC](https://www.ruby-forum.com/t/interesting-usages-of-struct/85876/2 "2007-02-17T04:00:40Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Joe\_at\_CodeGear](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/dec6dc/32.png) [@Joe\_at\_CodeGear](https://www.ruby-forum.com/u/Joe_at_CodeGear)\
**Post date:** [February 17, 2007, 9:39am UTC](https://www.ruby-forum.com/t/interesting-usages-of-struct/85876/3 "2007-02-17T09:39:59Z")

</div>

On 2/17/07, Joe at CodeGear [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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

---

<div class="post-metadata">

**Author:** ![Joe\_at\_CodeGear](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/dec6dc/32.png) [@Joe\_at\_CodeGear](https://www.ruby-forum.com/u/Joe_at_CodeGear)\
**Post date:** [February 17, 2007, 10:50am UTC](https://www.ruby-forum.com/t/interesting-usages-of-struct/85876/4 "2007-02-17T10:50:02Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Joe\_at\_CodeGear](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/dec6dc/32.png) [@Joe\_at\_CodeGear](https://www.ruby-forum.com/u/Joe_at_CodeGear)\
**Post date:** [February 17, 2007, 4:18pm UTC](https://www.ruby-forum.com/t/interesting-usages-of-struct/85876/5 "2007-02-17T16:18:39Z")

</div>

On Sun, Feb 18, 2007 at 12:00:15AM +0900, Phrogz wrote:

> On Feb 17, 1:39 am, “Robert D.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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

---

<div class="post-metadata">

**Author:** ![Joe\_at\_CodeGear](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/dec6dc/32.png) [@Joe\_at\_CodeGear](https://www.ruby-forum.com/u/Joe_at_CodeGear)\
**Post date:** [February 17, 2007, 4:00pm UTC](https://www.ruby-forum.com/t/interesting-usages-of-struct/85876/6 "2007-02-17T16:00:36Z")

</div>

On Feb 17, 1:39 am, “Robert D.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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! 🙂

---

<div class="post-metadata">

**Author:** ![Joe\_at\_CodeGear](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/dec6dc/32.png) [@Joe\_at\_CodeGear](https://www.ruby-forum.com/u/Joe_at_CodeGear)\
**Post date:** [February 18, 2007, 12:37am UTC](https://www.ruby-forum.com/t/interesting-usages-of-struct/85876/7 "2007-02-18T00:37:38Z")

</div>

On 2/17/07, Gregory S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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

---

<div class="post-metadata">

**Author:** ![Joe\_at\_CodeGear](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/dec6dc/32.png) [@Joe\_at\_CodeGear](https://www.ruby-forum.com/u/Joe_at_CodeGear)\
**Post date:** [February 18, 2007, 12:31am UTC](https://www.ruby-forum.com/t/interesting-usages-of-struct/85876/8 "2007-02-18T00:31:38Z")

</div>

On 2/17/07, Phrogz [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 

My pleasure 🙂  
Robert
