Reputation: 6628
I'm playing with some meta-programming concepts and wonder if something I want to do is simply possible.
There's simple DLS for events,
//test_events.rb
event 'monthly events are suspiciously high' do
true
end
and the script should shout out when event returns true, I try to do this without polluting global namespace with method event, and any instance variables. So I try something like this:
Dir.glob('*_events.rb').each do |file|
MyClass = Class.new do
define_method :event do |name, &block|
@events[name] = block
end
end
env = MyClass.new
env.instance_eval{@events = {}}
env.instance_eval{load(file)}
end
So for each *_events.rb file I would like to load it in context of MyClass (i know that with 2nd loop of Dir.glob#each it will complain about already defined const - not important now).
The problem is with env.instance_eval{load(file)}
code in test_events.rb is run in Object context, because I get
undefined method `event' for main:Object (NoMethodError)
Is there a way to do it? ( I try now in 1.9.3 but changing version up is not a problem since it's just exercise)
Upvotes: 1
Views: 736
Reputation: 79723
instance_eval
can take a String
as its argument instead of a block, so rather than load
(which as you suggest will load the file in the top level) you need to read the file contents into a string to pass in, something like:
env.instance_eval(File.read(file))
Upvotes: 4