Nicholas said:
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.