[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Variable Generation

Ari Brown

7/23/2007 9:19:00 PM

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


5 Answers

Morton Goldberg

7/23/2007 9:52:00 PM

0

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

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

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

Todd Benson

7/23/2007 9:55:00 PM

0

On 7/23/07, Ari Brown <ari@aribrown.com> wrote:
> 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?

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

F. Senault

7/23/2007 10:28:00 PM

0

Le 23 juillet 2007 à 23:19, Ari Brown 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
--
Dogs of war and men of hate With no cause, we don't discriminate
Discovery is to be disowned Our currency is flesh and bone Hell opened
up and put on sale Gather 'round and haggle For hard cash, we will lie
and deceive Even our masters don't know the web we weave (Pink Floyd)

Peña, Botp

7/24/2007 2:18:00 AM

0

From: Ari Brown [mailto:ari@aribrown.com]
# 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

Robert Klemme

7/24/2007 9:08:00 AM

0

2007/7/23, Ari Brown <ari@aribrown.com>:
> 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.

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