Joel VanderWerf wrote:
Tom Cloyd wrote:
Trying this for the first time, and, as usual, not quite getting it.
Everything I can find on kernal::binding tells me that I just call it and will get back a binding object which can be passed in a call to eval. But...it doesn't work for me.
In my main, I have a module required which contains a method I'm trying to call. For reasons irrelevant to this current problem, I'm using an eval of a string to do it, and want the method to execute in the environment of the main program. So...
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.
All examples I can find just do something like..
def meth_x
y = 1
return binding
end
Then 'y' is accessed using the binding. Well, if one can return a binding to initialize a variable -
z = meth_x
eval( "y", z ) # => "1"
Then why can't I simply pass 'binding' in an eval call FROM the calling environment?
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
Yes,
The binding that you pass into eval here only affects variables that are unbound in the string.
Man. Never read THAT anywhere else. Seems like essential information to associate with 'binding' method documentation, but it doesn't seem to be, anywhere I've looked.
In this case there are none. The x in M.meth is a bound variable in the scope of the method. Compare:
module M
def M.meth arg
p arg
end
end
x = 1
eval "M.meth(x)", binding # ==> 1
Interesting example. But it puzzles me. Why isn't 'x' considered bound in the scope of self? It's then passed in to M.meth as an argument, so why is 'binding' needed at all in this case? I don't understand why you did it this way - can you explain?
[...]
What are you trying to do?
I'm trying to execute a module method in the namespace of my main program which calls it. In outline:
I have a class which requires two files, each of which contains a module. I then include each module:
utilname = '../lib/setnet/Utils_' + File.basename( name ) + '.rb' #'name' passed in when class in instantiated
if File.exist?( utilname ) # it may not exist
require utilname
include Utils_db
end require '../lib/setnet/Utilities' # will always exist
include Utils
While I haven't found any authority who says this, it appears that 'include' can only occur at the top of a class definition. I only just figured this out, so I have about an hour+ experience with 'include'.
I thought the 'include' would essentially move my module methods into my main, as if they were physically there already. But that's not happening. I still have my namespace isolation problem:
When I call a module method from my main, it executes fine, until it tries to access a variable which would be plainly available of the module code were physically residing my class. It then crashes, as it finds only 'nil'.
I don't know how to fix this. I thought using 'include' would do it, but it seems to have no effect.
I don't want to just pass the method the data it needs, since in theory I won't know what that is. I want the method to take care of itself - to just have access to the calling program's namespace, which would solve all problems.
Can anyone suggest a solution?
Tom