【问题标题】:Why erb blocks concatenate the block content为什么erb块连接块内容
【发布时间】:2019-06-27 14:54:22
【问题描述】:

我有以下代码:

require 'erb'

def body &block
  content = block.call
  content = block.call
  content = block.call
  content
end

x = 2
template = ERB.new <<-EOF
  <% body do %>
     2
  <% end %>
EOF

template.run(binding)

当我执行它时输出2 2 2。为什么在 body 方法内每次调用 block.call 时都会连接块的内容?

为什么如果我使用以下模板就不会发生:

template = ERB.new <<-EOF
  <%= body do
     2
  end %>
EOF

我无法理解这里发生的事情。我在使用 rails 时遇到了这个问题,但将代码隔离到纯 Ruby 中以尝试了解问题所在。

【问题讨论】:

    标签: ruby-on-rails ruby erb


    【解决方案1】:

    这是因为 ERB 的工作原理。对于前一个模板,请参阅 erb 生成的 ruby​​ 源代码(template.src,以下是美化的):

    _erbout = +''
    _erbout.<< "  ".freeze
    body do
      _erbout.<< "\n     2\n  ".freeze      # <<-- this is the line that produces extra output
    end
    _erbout.<< "\n".freeze
    _erbout
    

    对于后者:

    _erbout = +''
    _erbout.<< "  ".freeze
    _erbout.<<(( body do
         2                                  # <<- and this time it is just plain ruby code
      end
    ).to_s)
    _erbout.<< "\n".freeze
    _erbout
    

    注意块在运行时如何输出到同一个缓冲区。

    实际上这是正常的并且被广泛使用,例如对于传递给each 方法的以下块,您希望每次运行的输出被连接起来:

    <% @items.each do |item| %>
      Item <%= item %>
    <% end %>
    

    【讨论】:

    • 谢谢!这正是我期望找到的答案:)!。新 ERB 没有 src 方法吗?
    猜你喜欢
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 2018-11-22
    • 2020-06-02
    • 2014-08-04
    • 1970-01-01
    • 2021-09-03
    相关资源
    最近更新 更多