Christopher Dicely wrote: > 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 > > > Thanks! That's very interesting, and is exactly what I was looking for. I was beginning to think it wasn't possible. I would not likely soon have found this solution on my own, so I'm very grateful for your assistance. Thanks for taking the time to respond. t. -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tom Cloyd, MS MA, LMHC - Private practice Psychotherapist Bellingham, Washington, U.S.A: (360) 920-1226 << tc / tomcloyd.com >> (email) << TomCloyd.com >> (website) << sleightmind.wordpress.com >> (mental health weblog) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~