Ruby 带收益的 erb 模板

Ruby erb templates with yield

我不明白为什么这段代码可以正常工作

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)

有什么想法吗?

这个问题与 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>

您应该将一个块传递给方法上下文,其中 binding 被调用,例如:

def foo
  binding
end

ERB.new('<%= yield %>').result(foo { 123 })
#=> "123"

请注意,您不能在方法体之外使用 yieldERB#result 只是在传递的绑定上下文中执行 ruby 代码,因此无论如何,您的绑定都应该在方法内部,因为 yield.