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)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~