# Dynamically created attributes

**URL:** <https://www.ruby-forum.com/t/dynamically-created-attributes/157490>\
**Category:** Ruby\
**Created:** [January 12, 2009, 9:25am UTC](https://www.ruby-forum.com/t/dynamically-created-attributes/157490 "2009-01-12T09:25:50Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dracos](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ea666f/32.png) [@dracos](https://www.ruby-forum.com/u/dracos)\
**Post date:** [January 12, 2009, 9:25am UTC](https://www.ruby-forum.com/t/dynamically-created-attributes/157490/1 "2009-01-12T09:25:50Z")

</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  
#Creates row1, row2, etc. depending on row arg  
def initialize(rows)  
row\_count = 1  
rows.times do  
instance\_eval “@row#{row\_count} = ‘xxx’”  
row\_count += 1  
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.

---

<div class="post-metadata">

**Author:** ![dracos](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ea666f/32.png) [@dracos](https://www.ruby-forum.com/u/dracos)\
**Post date:** [January 12, 2009, 10:00am UTC](https://www.ruby-forum.com/t/dynamically-created-attributes/157490/2 "2009-01-12T10:00:01Z")

</div>

Alle lunedÃ¬ 12 gennaio 2009, Peter M. ha scritto:

> ```
> instance_eval "@row#{row_count} = 'xxx'"
> row_count += 1
> 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.

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

attr\_reader :rows  
def initialize(rows)  
@rows = Array.new(rows){ ‘xxx’ }  
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

def   
@rows[idx]  
end

def []=(idx, value)  
@rows[idx] = value  
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))

I hope this helps

Stefano

---

<div class="post-metadata">

**Author:** ![dracos](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ea666f/32.png) [@dracos](https://www.ruby-forum.com/u/dracos)\
**Post date:** [January 12, 2009, 10:04am UTC](https://www.ruby-forum.com/t/dynamically-created-attributes/157490/3 "2009-01-12T10:04:09Z")

</div>

On Mon, Jan 12, 2009 at 9:25 AM, Peter M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> ```
> instance_eval "@row#{row_count} = 'xxx'"
> 
> ```

Maybe this is cleaner:

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

class Grid  
def initialize rows=0  
rows.times do |i|  
instance\_variable\_set “@row#{i}”, “initial value”  
singleton\_class.instance\_eval {attr\_accessor “row#{i}”}  
end  
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.

---

<div class="post-metadata">

**Author:** ![dracos](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ea666f/32.png) [@dracos](https://www.ruby-forum.com/u/dracos)\
**Post date:** [January 12, 2009, 10:10am UTC](https://www.ruby-forum.com/t/dynamically-created-attributes/157490/4 "2009-01-12T10:10:05Z")

</div>

On Mon, Jan 12, 2009 at 10:03 AM, Jesús Gabriel y  
Galán[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > rows.times do  
> > Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
> 
> =\> #\<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=”]

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.

---

<div class="post-metadata">

**Author:** ![dracos](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ea666f/32.png) [@dracos](https://www.ruby-forum.com/u/dracos)\
**Post date:** [January 12, 2009, 11:03am UTC](https://www.ruby-forum.com/t/dynamically-created-attributes/157490/5 "2009-01-12T11:03:34Z")

</div>

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

Cheers!

Peter
