Nicholas Van Weerdenburg wrote:
load works, but require would be nice.
I'm now trying to understand exactly how load works.
load(filename, wrap =false)
Didn't do what I wanted, so I went with the following
lines=File.read(filename)
eval(lines)
Which did work.
Docs for Kernel#load mention:
"In no circumstance will any local variables in the loaded file be
propagated to the loading environment."
Any ideas for how to use load and still set instance variables?
Did you mean _local_ vars? (If you assign instance vars in the top level of a loaded file, they will still be there in the "main" object at the top level when you get back to the file that is calling load.)
AFAIK, local vars are lost, unless you play games with proc bindings and eval:
$ cat a.rb
x=1
$pr = proc {}
$ cat b.rb
load 'a.rb'
p(eval("x", $pr))
$ ruby b.rb
1
But this just changes the problem: how to get the proc out of the loaded file without using something as gauche as a global var? (And never mind that using "eval" is _extremely_ gauche, and you will not be invited to ruby parties.)
Here's an alternative that Nobu Nokada suggested back in ruby-talk:62727:
$ cat c.rb
@ivar = 1
CONST = 2
def self.meth; 3; end
$ cat d.rb
class Module
def load_in_module(file)
module_eval(IO.read(file), File.expand_path(file))
end
end
module M
load_in_module('c.rb')
p @ivar
end
p M::CONST
p M.meth
p @ivar
$ ruby d.rb
1
2
3
nil
This lets you can capture top-level constants, methods, and attrs from the loaded file. That's the basic idea in my script lib (http://redshift.sourceforge.net/script/\), but it adds some bells and whistles: it defines require so that local dependencies within the loaded file work; there is an autoscript (like autoload); meaningful exceptions; compact syntax; a rudimentary facility for passing params _in_ to a loaded script.