From: matt@... (matt neuburg) Date: 2009-03-14T11:32:52+09:00 Subject: Re: Problem With eval and each_index Michael W. Ryder <_mwryder@worldnet.att.net> wrote: > I am trying to set a group of variables to values stored in a tab > delimited string. I have no problem splitting the string into an array, > call it e, or in putting the variable names in a second array, call it > v. The problem arises when I try to merge the two together. If I enter: > irb(main):073:0> p v > ["name", "street", "city", "state", "zip", "*", "telephone"] > => nil > irb(main):074:0> p e > ["John Doe", "123 Main St", "Anywhere", "US", "01234-5678", "ab123", > "1234567890"] > => nil > irb(main):075:0> eval "#{v[0]} = e[0]" > => "John Doe" > irb(main):076:0> p name > "John Doe" > => nil > > it works as I want. But when I try: > irb(main):077:0> v.each_index {|i| eval "#{v[i]} = e[0]"} > => ["name", "street", "city", "state", "zip", "*", "telephone"] > > and then enter: puts zip > it returns with a NameError saying that the variable was undefined. Inside a block, local variables are local to the block. So, you're creating all those local variables and then the block ends and they are all thrown away. Why do you need variables called "name" (etc.) anyway? Why not use a hash, so that h["name"] contains the name ("John Doe"), h["street"] contains the street, and so on? So: h = Hash.new v.zip(e).each {|k,v| h[k]=v} Notice that even here we define h before we get to the block. That way, the block's h is our h; it is global to the block. An even cooler approach is a struct: Person = Struct.new(*(v.map {|i| i.to_sym})) p = Person.new(*e) Now you've got an object, p, where p.name is "John Doe" and so on. m. -- matt neuburg, phd = matt@tidbits.com, http://www.tidbits.com/matt/ Leopard - http://www.takecontrolbooks.com/leopard-customizing.html AppleScript - http://www.amazon.com/gp/product/0596102119 Read TidBITS! It's free and smart. http://www.tidbits.com