Ruby binding 对象可以携带一个块?

cicholgricenchos · 2015年03月01日 · 1660 次阅读
require 'erb'

temp ="<%= yield %>"

erb = ERB.new(temp)

def get_binding
  binding
end

p erb.result(get_binding{1})  #=> "1"

b = get_binding{1}
p erb.result(b)  #=> "1"

p b.class  #=> Binding

p erb.result(binding{1})  #=> no block given (yield) (LocalJumpError)

Kernel.binding方法不接受参数,ERB#result接受一个binding对象,这里get_binding方法接受了一个块,但是当这个方法返回的时候,那个块应该就被弃置了啊。

获得b可以知道b确实是一个Binding对象,然而直接传入erb.result却可以起到块的作用,b这个对象看起来携带了一个块。

而且erb.result(binding{1})在语法的角度看和get_binding应该没有区别,但是却报错了,其中肯定有一些特殊的机制在工作。

disasm一下代码的话发现二者对binding的调用是不同的,一个是send,一个是send_simple,说明这个语句可能有两种不同的实现方式。然后就再没办法获得更多线索了。

更新

stackoverflow上的回答是在函数内产生的binding,包括当时所有的上下文,也包含了传入的块,yield便可以此访问函数调用时的block,用“携带”一词可能不太合适,虽然表现上是这样。binding在函数内和函数外生成是这种差异的原因。

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册