我有以下代码:
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
。为什么在block.call
方法内对body
的每次调用中,它都是将块的内容串联在一起?
为什么如果我使用以下模板,它不会发生:
template = ERB.new <<-EOF
<%= body do
2
end %>
EOF
我无法确定这里发生的事情。我在rails上遇到了这个问题,但是将代码隔离到普通的Ruby中,试图了解问题所在。
答案 0 :(得分:3)
这是因为ERB的工作原理。有关旧模板,请参见由erb生成的红宝石源(以下为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 %>