Конкатенация процессов с сохранением возможностей переоценки контекста

Я хочу объединить тела двух процедур. Но в отличие от здесь, здесь есть поворот. Результирующий процесс должен сохранить исходную способность экземпляров 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
}

Но я не удивлюсь, если кто-то придумает что-то более идиоматическое

Другие вопросы по тегам