On Thu, Apr 23, 2009 at 6:33 PM, Tom Cloyd <tomcloyd / comcast.net> wrote: > Rick DeNatale wrote: >> >> On Thu, Apr 23, 2009 at 3:09 AM, Joel VanderWerf >> <vjoel / path.berkeley.edu> wrote: >> >>> >>> Tom Cloyd wrote: >>> >> >> >>>> >>>> eval( "moduleName.methodName", binding) >>>> >>>> Causes *crash* due to by attempt to access a variable which exists in >>>> the >>>> calling environment but not in the module. In spite of passing the >>>> binding, >>>> the method knows nothing of the variable. It's not working. >>>> >>>> >>> >>> You've got something like this, right? >>> >>> module M >>> def M.meth >>> p x >>> end >>> end >>> >>> x = 1 >>> eval "M.meth", binding # Undefined variable x >>> >>> >>> The binding that you pass into eval here only affects variables that are >>> unbound in the string. In this case there are none. The x in M.meth is a >>> bound variable in the scope of the method. >>> >> >> And to stress the obvious >> >> eval "some string" >> >> which uses the current binding, is exactly equivalent to >> >> eval "some string", binding >> >> Assuming that binding is a call to Kernel#binding and not a local >> variable. >> >> So >> >> eval "M.meth" >> and >> eval "M.meth", binding >> >> will both do the same thing, including throwing any exceptions. >> >> > > So, how do I get M.meth to execute in the namespace of my main? I thought > 'binding' packaged up that namespace and I could then pass it to the method. No, it packages it so you can pass it to eval, which is useful if you want to call eval from a different point than where you capture the binding. > I want M.meth to have access to all variables in main's namespace - well, > instance variables, anyway. How do I do that? If you want to access instance variables from the calling scope inside a method call (on a different object), you could pass self from the calling point as an argument to the method, and use instance_eval in the method. E.g.: irb(main):001:0> module M irb(main):002:1> def M.meth irb(main):003:2> end irb(main):004:1> end => nil irb(main):005:0> module M irb(main):006:1> def M.meth(target) irb(main):007:2> puts target.instance_eval { @foo } irb(main):008:2> end irb(main):009:1> end => nil irb(main):010:0> class C irb(main):011:1> def initialize(val) irb(main):012:2> @foo = val irb(main):013:2> end irb(main):014:1> def test irb(main):015:2> M.meth(self) irb(main):016:2> end irb(main):017:1> end => nil irb(main):018:0> c = C.new(1) => #<C:0x2bbd440 @foo=1> irb(main):019:0> c.test 1 => nil