我无法理解为什么这段代码可以正常运行
def func
ERB.new('<%= yield %>').result(binding)
end
func { 123 } # => it prints 123 as expected
但是这个不起作用并引发异常
ERB.new('<%= yield %>').result(binding) { 123 } # => LocalJumpError: no block given (yield)
有什么想法吗?
答案 0 :(得分:3)
这个问题与ERB无关,是因为yield
的工作方式。 期望在消息正文中调用Yield,并期望一个块产生它。让我们举个例子
# This is equivalent to
# def func
# ERB.new('<%= yield %>').result(binding)
# end
def test_print
yield
end
如果我们调用没有块的方法
irb(main):038:0> test_print
LocalJumpError: no block given (yield)
from (irb):36:in `test_print'
from (irb):38
from /Users/agupta/.rvm/rubies/ruby-2.4.0/bin/irb:11:in `<main>'
irb(main):039:0>
如果我们用块
调用该方法irb(main):039:0> test_print { "hello world" }
=> "hello world"
irb(main):040:0>
在后一种情况下
ERB.new('<%= yield %>').result(binding) { 123 }
由于yield
位于邮件正文之外且您无法执行
irb(main):042:0> yield.tap { "hello world" }
LocalJumpError: no block given (yield)
from (irb):42
from /Users/agupta/.rvm/rubies/ruby-2.4.0/bin/irb:11:in `<main>'
irb(main):043:0>
答案 1 :(得分:3)
您应该将块传递给方法上下文,其中binding
被调用,例如:
def foo
binding
end
ERB.new('<%= yield %>').result(foo { 123 })
#=> "123"
请注意,您不能在方法正文之外使用yield
。
ERB#result
只是在传递绑定的上下文中执行ruby代码,因此你的绑定应该在方法内部,因为yield
。