Конкатенация процессов с сохранением возможностей переоценки контекста
Я хочу объединить тела двух процедур. Но в отличие от здесь, здесь есть поворот. Результирующий процесс должен сохранить исходную способность экземпляров instance_eval.
Это может показаться немного запутанным, так что вот мой пример использования.
Я реализую другой язык как внутренний DSL в Ruby. Упрощенная реализация:
class Interpreter
def self.run(&program)
Interpreter.new.instance_eval(&program)
end
def initialize
@variables = {}
end
def assign_variable(name, value)
@variables[name] = value
end
def display(name)
puts @variables[name]
end
end
Interpreter.run do
assign_variable :foo, 42
display :foo
end
Если я разделю тело процедуры на два других:
assignment = proc { assign_variable :foo, 42 }
printing = proc { display :foo }
combined = proc { assignment.call; printing.call }
Interpreter.run(&combined)
Это не будет работать, потому что combined
proc - это instance_eval-ed, но assignment
а также printing
ПРОЦЫ оцениваются в контексте места, где они были определены.
Причина, по которой я хочу разделить исходный процесс, состоит в том, что я могу СУШИТЬ свои тесты.
1 ответ
Решение
Ты можешь сделать
combined = proc {
instance_eval &assignment
instance_eval &printing
}
Но я не удивлюсь, если кто-то придумает что-то более идиоматическое