Я играю с некоторыми концепциями метапрограммирования и задаюсь вопросом, возможно ли что-то, что я хочу сделать, просто.Как загрузить файл в контексте объекта
Там просто DLS для событий,
//test_events.rb
event 'monthly events are suspiciously high' do
true
end
и сценарий должен кричать, когда событие возвращает истину, я пытаюсь сделать это, не загрязняя глобальное пространство имен методы события, и любой переменный экземпляр. Так что я пытаюсь что-то вроде этого:
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
Таким образом, для каждого * _events.rb файла Я хотел бы, чтобы загрузить его в контексте MyClass (я знаю, что с 2-ой петле Dir.glob # каждый будет жаловаться уже определенный const - не важно сейчас).
Проблема с env.instance_eval{load(file)}
кода в test_events.rb выполняется в контексте объекта, потому что я получаю
undefined method `event' for main:Object (NoMethodError)
Есть ли способ сделать это? (Я стараюсь сейчас в 1.9.3, но изменения версии вверх не является проблемой, так как это просто упражнения)
вы можете захотеть взглянуть на эту BlogPost для пошагового о том, как создать пользовательский DSL в Ruby: http://robots.thoughtbot.com/writing-a-domain-specific-language-in-ruby –
Спасибо, это действительно интересно читать. Тем не менее мне не удалось найти ответ на мой вопрос. Дело в том, что я знаю, как сделать DSL, который будет работать следующим образом: «Redflag.register do Событие« Месячные события подозрительно высокие »do true end end ' Это довольно просто. Но позвольте мне перефразировать мой вопрос: как вызвать Kernel # load в контексте любого экземпляра объекта. Из всех моих попыток похоже, что он всегда будет вызван в контексте объекта объекта. Является ли это возможным? – meta
AFAIK no, 'load' не зависит от контекста - он загружает код в глобальную область. –