From: Robert Klemme Date: 2010-10-07T20:06:53+09:00 Subject: Re: setting local variables in a binding On Thu, Oct 7, 2010 at 4:19 AM, John Sikora wrote: > Tony Arcieri wrote: >> Note that "binding" is the default argument of eval if you don't specify >> one, so capturing binding as a variable and passing it explicitly is >> redundant. > > You are correct but the problem 'persists'. The following irb session in > 1.9.2 shows the same thing without the binding: > > irb(main):001:0> eval("x=5") > => 5 > irb(main):002:0> x > NameError: undefined local variable or method `x' for main:Object >        from (irb):2 >        from C:/Ruby192/bin/irb:12:in `
' > irb(main):003:0> x=4 > => 4 > irb(main):004:0> eval("x=5") > => 5 > irb(main):005:0> x > => 5 > irb(main):006:0> The reason is that Ruby looks at the source code to find out which are local variables. This is basically the same as doing 13:00:57 ~$ ruby19 -e 'def f;puts "x=10";p x end;f' x=10 -e:1:in `f': undefined local variable or method `x' for main:Object (NameError) from -e:1:in `
' 13:00:59 ~$ ruby19 -e 'def f;eval "x=10";p x end;f' -e:1:in `f': undefined local variable or method `x' for main:Object (NameError) from -e:1:in `
' 13:01:02 ~$ In other words: the interpreter does not know that there is an assignment to x in the eval code so x is undefined. > In order for this to work, the x needs to be @x per the following irb > session (again 1.9.2): > > irb(main):001:0> eval("@x=5") > => 5 > irb(main):002:0> @x > => 5 > irb(main):003:0> That's an instance variable which is a completely different beast. > The behavior seen in the first irb session was the same in 1.8.6, 1.9.1, > and 1.9.2 when run standalone. However, it works in irb for 1.8.6 (x w/o > the @). irb has some specialities with handling local variables which is the reason it behaves differently. The reason is that it will not parse the code in one go because it only ever sees a chunk (every time you hit enter). If the interpreter's regular behavior would be retained you could not use local variables in irb which would be inconvenient. > I have sometimes seen 'local' or 'unassociated' instance variables (not > sure if my terminology is correct) Not sure what you actually mean by that. > in example programs and I have > wondered why they are used. I guess this is one reason although most > people don't like to use eval. The reasons against eval are more in the area of safety and performance. If you know which variable you want to assign you can use it directly. If you do not know you typically use a Hash. > I use eval in personal scripts since it is so convenient. Had to go back > and look at some code to remind myself how I got around the behavior > seen in the first irb session. I don't remember if I read about using > the local instance variable or just played around with it until I got it > to work. What do you use eval for? In cases where the set of variables is not fixed at coding time chances are that you usually want a Hash. Using eval should be really be rare and for specific cases but not an everyday habit IMHO. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/