From: Brian Candler Date: 2009-08-11T17:44:51+09:00 Subject: Re: instance_variables vs. local_variables David Whetstone wrote: > This clears up a misperception I had when trying similar examples. For > example, while your example works, the following does not: > > eval("a=1") > p eval("a") # ==> NameError: undefined local variable or method ‘a’ > for main:Object > > My incorrect assumption was that the object returned by Kernel::binding > (implicitly called by eval when no binding is specified) represented the > _actual_ bindings of the current context. But it's really only a copy, > with each call to eval retrieving a fresh copy. In practice, this: As far as I understand, it's not exactly a "copy". Rather, each binding is a linked list of frames, and if you create a new binding it's the same linked list but with an empty frame on top. So if you create a new variable it goes in the top frame, but if you are searching for an existing variable it hunts back along the list. > eval("a=1") > > is roughly equivalent to this: > > do > a = 1 > end > > in that local symbols introduced inside are not accessible outside. Yes. > So, > there really is no way to affect the bindings of an existing context, > since only a copy of the current bindings can ever be acquired. No, because you can pass a binding around as an object, which means you can manipulate it even when it isn't the 'current' binding: def define_a(b) eval "a=1", b end define_a(binding) puts local_variables.inspect # prints ["a"] You can also implicitly do this using the binding of a block: def another_a(&blk) eval "a=1", blk.binding yield end another_a do puts local_variables.inspect # prints ["a"] end Furthermore, if you are prepared to jump through hoops, you can get other bindings without passing them around. Google for "binding_of_caller" or "Binding.of_caller" -- Posted via http://www.ruby-forum.com/.