# Dynamically created attributes

**URL:** <https://rubytalk.org/t/dynamically-created-attributes/51106>\
**Category:** ruby-talk\
**Created:** [12 January 2009 08:25 UTC](https://rubytalk.org/t/dynamically-created-attributes/51106 "2009-01-12T08:25:08Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Peter\_Marks](https://avatars.discourse-cdn.com/v4/letter/p/fbc32d/32.png) [@Peter\_Marks](https://rubytalk.org/u/Peter_Marks)\
**Post date:** [12 January 2009 08:25 UTC](https://rubytalk.org/t/dynamically-created-attributes/51106/1 "2009-01-12T08:25:08Z")

</div>

I'd like to specify a quantity of object attributes when creating an  
instance of an object. For example, I would like to create a Grid object  
with 4 different 'row' attributes like this: Grid.new(4). Here's some  
dirty code that does that:

class Grid  
&nbsp;&nbsp;#Creates row1, row2, etc. depending on row arg  
&nbsp;&nbsp;def initialize(rows)  
&nbsp;&nbsp;&nbsp;&nbsp;row\_count = 1  
&nbsp;&nbsp;&nbsp;&nbsp;rows.times do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance\_eval "@row#{row\_count} = 'xxx'"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row\_count += 1  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
end

It's dirty, but it creates the attributes. I don't see how to  
dynamically create accessor methods for all these attributes though. Any  
suggestions? I sense there's a better way to do this.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Stefano\_Crocco](https://avatars.discourse-cdn.com/v4/letter/s/5f9b8f/32.png) [@Stefano\_Crocco](https://rubytalk.org/u/Stefano_Crocco)\
**Post date:** [12 January 2009 08:58 UTC](https://rubytalk.org/t/dynamically-created-attributes/51106/2 "2009-01-12T08:58:33Z")

</div>

Alle lunedì 12 gennaio 2009, Peter Marks ha scritto:

> I'd like to specify a quantity of object attributes when creating an  
> instance of an object. For example, I would like to create a Grid object  
> with 4 different 'row' attributes like this: Grid.new(4). Here's some  
> dirty code that does that:
> 
> class Grid  
> &nbsp;&nbsp;#Creates row1, row2, etc. depending on row arg  
> &nbsp;&nbsp;def initialize(rows)  
> &nbsp;&nbsp;&nbsp;&nbsp;row\_count = 1  
> &nbsp;&nbsp;&nbsp;&nbsp;rows.times do  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance\_eval "@row#{row\_count} = 'xxx'"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row\_count += 1  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end  
> end
> 
> It's dirty, but it creates the attributes. I don't see how to  
> dynamically create accessor methods for all these attributes though. Any  
> suggestions? I sense there's a better way to do this.

Well, the first thing I can think of is to replace your n instance variables  
with a single instance variable @rows which will be an array and contain the  
rows. Something like this:

class Grid

&nbsp;&nbsp;attr\_reader :rows  
&nbsp;&nbsp;def initialize(rows)  
&nbsp;&nbsp;&nbsp;&nbsp;@rows = Array.new(rows){ 'xxx' }  
&nbsp;&nbsp;end

end

If you don't want to make the array availlable from outside the instance, you  
can skip the attr\_readr line and provide methods to directly access the rows.  
For example, you can define and = methods as array does:

class Grid

&nbsp;&nbsp;def (idx)  
&nbsp;&nbsp;&nbsp;&nbsp;@rows[idx]  
&nbsp;&nbsp;end

&nbsp;&nbsp;def =(idx, value)  
&nbsp;&nbsp;&nbsp;&nbsp;@rows[idx] = value  
&nbsp;&nbsp;end

end

If you truly want to use an instance variable for each row, see the  
documentation about instance\_variable\_set and look at the section "Object  
specific classes" in the "Classes and Objects" chapter of the online edition  
of the Pickaxe book  
([Programming Ruby: The Pragmatic Programmer's Guide](http://www.ruby-doc.org/docs/ProgrammingRuby/html/classes.html%5C))

I hope this helps

Stefano

---

<div class="post-metadata">

**Author:** ![Jesus\_Gabriel\_y\_Gala](https://avatars.discourse-cdn.com/v4/letter/j/96bed5/32.png) [@Jesus\_Gabriel\_y\_Gala](https://rubytalk.org/u/Jesus_Gabriel_y_Gala)\
**Post date:** [12 January 2009 09:02 UTC](https://rubytalk.org/t/dynamically-created-attributes/51106/3 "2009-01-12T09:02:48Z")

</div>

Maybe this is cleaner:

class Object  
&nbsp;&nbsp;def singleton\_class  
&nbsp;&nbsp;&nbsp;&nbsp;class \<\< self; self; end  
&nbsp;&nbsp;end  
end

class Grid  
&nbsp;&nbsp;def initialize rows=0  
&nbsp;&nbsp;&nbsp;&nbsp;rows.times do |i|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance\_variable\_set "@row#{i}", "initial value"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;singleton\_class.instance\_eval {attr\_accessor "row#{i}"}  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
end

irb(main):020:0\> a = Grid.new 3  
=\> #\<Grid:0xb7c02008 @row0="initial value", @row2="initial value",  
@row1="initial value"\>  
irb(main):021:0\> a.methods.grep /row/  
=\> ["row0", "row0=", "row1", "row1=", "row2", "row2="]

Hope this helps,

Jesus.

> **···**
>
> On Mon, Jan 12, 2009 at 9:25 AM, Peter Marks \<petertmarks@gmail.com\> wrote:
> 
> > I'd like to specify a quantity of object attributes when creating an  
> > instance of an object. For example, I would like to create a Grid object  
> > with 4 different 'row' attributes like this: Grid.new(4). Here's some  
> > dirty code that does that:
> > 
> > class Grid  
> > #Creates row1, row2, etc. depending on row arg  
> > def initialize(rows)  
> > &nbsp;&nbsp;&nbsp;row\_count = 1  
> > &nbsp;&nbsp;&nbsp;rows.times do  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance\_eval "@row#{row\_count} = 'xxx'"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row\_count += 1  
> > &nbsp;&nbsp;&nbsp;end  
> > end  
> > end
> > 
> > It's dirty, but it creates the attributes. I don't see how to  
> > dynamically create accessor methods for all these attributes though. Any  
> > suggestions? I sense there's a better way to do this.  
> > --  
> > Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Jesus\_Gabriel\_y\_Gala](https://avatars.discourse-cdn.com/v4/letter/j/96bed5/32.png) [@Jesus\_Gabriel\_y\_Gala](https://rubytalk.org/u/Jesus_Gabriel_y_Gala)\
**Post date:** [12 January 2009 09:07 UTC](https://rubytalk.org/t/dynamically-created-attributes/51106/4 "2009-01-12T09:07:29Z")

</div>

Ooops, my solution starts with 0, while you wanted to start with 1.  
Anyway, an easy change. Nevertheless, I agree with Stefano that this  
would be better off implemented as an array, instead of having  
individual variables for each "field".

Jesus.

> **···**
>
> On Mon, Jan 12, 2009 at 10:03 AM, Jesús Gabriel y Galán \<jgabrielygalan@gmail.com\> wrote:
> 
> > On Mon, Jan 12, 2009 at 9:25 AM, Peter Marks \<petertmarks@gmail.com\> wrote:
> > 
> > > I'd like to specify a quantity of object attributes when creating an  
> > > instance of an object. For example, I would like to create a Grid object  
> > > with 4 different 'row' attributes like this: Grid.new(4). Here's some  
> > > dirty code that does that:
> > > 
> > > class Grid  
> > > #Creates row1, row2, etc. depending on row arg  
> > > def initialize(rows)  
> > > &nbsp;&nbsp;&nbsp;row\_count = 1  
> > > &nbsp;&nbsp;&nbsp;rows.times do  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance\_eval "@row#{row\_count} = 'xxx'"  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row\_count += 1  
> > > &nbsp;&nbsp;&nbsp;end  
> > > end  
> > > end
> > > 
> > > It's dirty, but it creates the attributes. I don't see how to  
> > > dynamically create accessor methods for all these attributes though. Any  
> > > suggestions? I sense there's a better way to do this.  
> > > --  
> > > Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).
> > 
> > Maybe this is cleaner:
> > 
> > class Object  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def singleton\_class  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class \<\< self; self; end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > end
> > 
> > class Grid  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def initialize rows=0  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rows.times do |i|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance\_variable\_set "@row#{i}", "initial value"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;singleton\_class.instance\_eval {attr\_accessor "row#{i}"}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > end
> > 
> > irb(main):020:0\> a = Grid.new 3  
> > =\> #\<Grid:0xb7c02008 @row0="initial value", @row2="initial value",  
> > @row1="initial value"\>  
> > irb(main):021:0\> a.methods.grep /row/  
> > =\> ["row0", "row0=", "row1", "row1=", "row2", "row2="]

---

<div class="post-metadata">

**Author:** ![Peter\_Marks](https://avatars.discourse-cdn.com/v4/letter/p/fbc32d/32.png) [@Peter\_Marks](https://rubytalk.org/u/Peter_Marks)\
**Post date:** [12 January 2009 10:02 UTC](https://rubytalk.org/t/dynamically-created-attributes/51106/5 "2009-01-12T10:02:53Z")

</div>

Thanks for the help guys! The arrays sound like a much more suitable way  
around this problem. Overthought this one.

Cheers!

Peter

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
