# Variable Generation

**URL:** <https://www.ruby-forum.com/t/variable-generation/110176>\
**Category:** Ruby\
**Created:** [July 23, 2007, 11:21pm UTC](https://www.ruby-forum.com/t/variable-generation/110176 "2007-07-23T23:21:24Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ari\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a698b9/32.png) [@Ari\_B](https://www.ruby-forum.com/u/Ari_B)\
**Post date:** [July 23, 2007, 11:21pm UTC](https://www.ruby-forum.com/t/variable-generation/110176/1 "2007-07-23T23:21:24Z")

</div>

yes, I mean spontaneously generated variables.

Assume we have an array:  
array = %w(yea cool awesome stuff)  
Now, I’m looking to make a variable corresponding to the item. so that:

yea = “yea”  
cool = “cool”  
awesome = “awesome”  
stuff = “stuff”

My current method (which FAILS) is using eval  
array.each {|item| eval(item + “=”#{item}"") }

I tested this with a puts instead of eval, and it comes out exactly  
as it should. But when I try to use the variable, I get a  
undefined local variable or method  
error.

Bwah?  
-------------------------------------------------------|  
~ Ari  
crap my sig won’t fit

---

<div class="post-metadata">

**Author:** ![Ari\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a698b9/32.png) [@Ari\_B](https://www.ruby-forum.com/u/Ari_B)\
**Post date:** [July 23, 2007, 11:53pm UTC](https://www.ruby-forum.com/t/variable-generation/110176/2 "2007-07-23T23:53:12Z")

</div>

On Jul 23, 2007, at 5:19 PM, Ari B. wrote:

> stuff = “stuff”
> 
> My current method (which FAILS) is using eval  
> array.each {|item| eval(item + “=”#{item}"") }
> 
> I tested this with a puts instead of eval, and it comes out exactly  
> as it should. But when I try to use the variable, I get a undefined  
> local variable or method error.

Your problem likely results from the scoping rules for local  
variables. I think it would work as you expect if you used global or  
instance variables. However, for this kind of thing, I usually prefer  
a hash. You might consider using something like:

WORDS = %w(yea cool awesome stuff)  
DICTIONARY = {}  
WORDS.each { |w| DICTIONARY[w.to\_sym] = w }  
DICTIONARY[:cool] # =\> “cool”

Regards, Morto

---

<div class="post-metadata">

**Author:** ![Ari\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a698b9/32.png) [@Ari\_B](https://www.ruby-forum.com/u/Ari_B)\
**Post date:** [July 23, 2007, 11:57pm UTC](https://www.ruby-forum.com/t/variable-generation/110176/3 "2007-07-23T23:57:28Z")

</div>

On 7/23/07, Ari B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> My current method (which FAILS) is using eval  
> array.each {|item| eval(item + “="#{item}"”) }
> 
> I tested this with a puts instead of eval, and it comes out exactly  
> as it should. But when I try to use the variable, I get a  
> undefined local variable or method  
> error.
> 
> Bwah?

Your new variables only have scope within the block.

I suppose you could do use global variables:

irb\> a = %w{ yea cool awesome stuff }  
=\> [“yea”, “cool”, “awesome”, “stuff”]  
irb\> a.each { |elem| eval(“$” + elem + “="#{elem}"”) }  
=\> [“yea”, “cool”, “awesome”, “stuff”]  
irb\> $yea  
=\> “yea”

Yuck. Is there some reason you couldn’t just use a hash, maybe?

irb\> h = {}  
=\> {}  
irb\> %w{ yea cool awesome stuff }.each { |e| h[e.intern] = e }  
=\> [“yea”, “cool”, “awesome”, “stuff”]  
irb\> h[:yea]  
=\> “yea”

Todd

---

<div class="post-metadata">

**Author:** ![Ari\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a698b9/32.png) [@Ari\_B](https://www.ruby-forum.com/u/Ari_B)\
**Post date:** [July 24, 2007, 12:36am UTC](https://www.ruby-forum.com/t/variable-generation/110176/4 "2007-07-24T00:36:37Z")

</div>

Le 23 juillet 2007 à 23:19, Ari B. a écrit :

> My current method (which FAILS) is using eval  
> array.each {|item| eval(item + “=”#{item}"") }

When the eval is run, you’re in the context of the block. If the  
variable exists beforehand, you can use it. Otherwise, I don’t know if  
it can be done.

You can try to make an accessor method, though :

[‘a’, ‘b’, ‘c’].each do |t| eval \<\<-EOE  
def #{t}  
‘#{t}’  
end  
EOE  
end  
puts a  
puts b

On the other hand, you can always use instance variables, with the  
following code for instance :

[‘a’, ‘b’, ‘c’].each do |t|  
self.instance\_variable\_set("@#{t}".to\_sym, t)  
end  
puts @a  
puts @b

In some contexts, I guess you could also call attr\_accessor to generate  
the accessors, but I can’t wrap my mind around it at this hour… 🙂

Fred

---

<div class="post-metadata">

**Author:** ![Ari\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a698b9/32.png) [@Ari\_B](https://www.ruby-forum.com/u/Ari_B)\
**Post date:** [July 24, 2007, 11:09am UTC](https://www.ruby-forum.com/t/variable-generation/110176/5 "2007-07-24T11:09:34Z")

</div>

2007/7/23, Ari B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> My current method (which FAILS) is using eval  
> array.each {|item| eval(item + “="#{item}"”) }
> 
> I tested this with a puts instead of eval, and it comes out exactly  
> as it should. But when I try to use the variable, I get a  
> undefined local variable or method  
> error.

There are various issues to your approach, namely that you cannot  
reference local variables that are defined in an eval block and not  
defined in the code around it. Ruby needs to read the variable name  
literally if you want do access it. You cannot do something like

some\_magic\_that\_sets\_x()  
puts x

Your probably is probably better solved by either using a Hash or  
using OpenStruct.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![Ari\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a698b9/32.png) [@Ari\_B](https://www.ruby-forum.com/u/Ari_B)\
**Post date:** [July 24, 2007, 4:19am UTC](https://www.ruby-forum.com/t/variable-generation/110176/6 "2007-07-24T04:19:12Z")

</div>

From: Ari B. [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]

# yes, I mean spontaneously generated variables.

you don’t like Struct

irb(main):006:0\> v = Struct.new(:yea, :cool, :awesome, :stuff)  
=\> #Class:0xb7dd9048  
irb(main):007:0\> v1 = v.new(“yeah”,“cool”,“awesome”,“stuff”)  
=\> #\<struct #Class:0xb7dd9048 yea=“yeah”, cool=“cool”,  
awesome=“awesome”, stuff=“stuff”\>  
irb(main):008:0\> v1.yea  
=\> “yeah”  
irb(main):009:0\> v1.yea = “heheh”  
=\> “heheh”  
irb(main):010:0\> v1.yea  
=\> “heheh”  
irb(main):011:0\> v2 = v.new(“yeah”,“cool”,“awesome”,“stuff”)  
=\> #\<struct #Class:0xb7dd9048 yea=“yeah”, cool=“cool”,  
awesome=“awesome”, stuff=“stuff”\>  
irb(main):012:0\> v2.yea  
=\> “yeah”

you can play w your var groups …

irb(main):014:0\> v3 = v1  
=\> #\<struct #Class:0xb7dd9048 yea=“heheh”, cool=“cool”,  
awesome=“awesome”, stuff=“stuff”\>  
irb(main):015:0\> v3.yea  
=\> “heheh”

but i wish Struct vars or basically ruby’s accessors can be initialized,  
like

v = Struct.new(:yea = “yeah!”, :cool = “cool”, :awesome = “!”, :stuff =  
“:)” )

less repitition ie.

kind regards -botp
