【问题标题】:Ruby erb templates with yield带有产量的 Ruby erb 模板
【发布时间】:2018-03-21 00:01:15
【问题描述】:

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

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)

有什么想法吗?

【问题讨论】:

    标签: ruby erb yield


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-17
        • 2016-10-11
        • 2010-11-23
        相关资源
        最近更新 更多