更改块的绑定

时间:2014-08-05 15:32:37

标签: ruby lambda scope proc

我正在尝试编写一个可以捕获代码块并随后更改范围/闭包中的变量的类。

class BlockCapture

  attr_reader :block

  def initialize(&block)
    @block = block
    @scope_additions = {}
  end

  def merge_into_scope(values = {})
    @scope_additions = @scope_additions.merge(values)
  end

  def mutated_block
    # some code that merges the scope additions into the binding
    # and returns the context
  end
end

captured_block = BlockCapture.new do
  future_variable.upcase
end

captured_block.block.call # This should trigger a NameError, as `future_variable` is not in scope.

captured_block.merge_into_scope(future_variable: "I was added to the scope")

captured_block.mutated_block.call # This should work
=> "I WAS ADDED TO THE SCOPE"

我不知道如何将变量合并到范围中。

我已尝试在块变量上调用绑定方法,但每次都返回一个新绑定,因此它似乎是原始块绑定的引用的副本而不是引用。

irb(main):078:0> capture.block.binding
=> #<Binding:0x007fa38292e398>
irb(main):079:0> capture.block.binding
=> #<Binding:0x007fa382925f18>
irb(main):080:0> capture.block.binding
=> #<Binding:0x007fa38291d908>

1 个答案:

答案 0 :(得分:0)

作为答案,即使我不确定它会有所帮助,因为评论中没有空格。看起来您可以使用特定绑定运行eval,例如使用当前绑定,在 之后创建

bind_lambda = -> (bind, x) { bind.eval x }
#=> #<Proc:0x007fec943b85e8@(pry):1 (lambda)>

首先尝试以错误结束,如预期的那样:

bind_lambda.call binding, 'future_var'
NameError: undefined local variable or method `future_var' for main:Object
from (pry):2:in `__pry__'

但声明局部变量后:

future_var = "here be dragons"
#=> "here be dragons"

我们可以达到它:

bind_lambda.call binding, 'future_var'
#=> "here be dragons"

这是因为binding是当前环境。