Ruby 雇员再培训局内部程序

Ruby 雇员再培训局内部程序,ruby,Ruby,当我尝试使用普通Ruby为ERB中的块实现多个content\u时,这里发生了一些奇怪的事情,我无法理解 这是我的密码: # helper.rb require 'erb' def render(path) ERB.new(File.read(path)).result(binding) end def content_for(key, &block) content_blocks[key.to_sym] = block end def yield_content(key)

当我尝试使用普通Ruby为ERB中的块实现多个
content\u时,这里发生了一些奇怪的事情,我无法理解

这是我的密码:

# helper.rb
require 'erb'

def render(path)
  ERB.new(File.read(path)).result(binding)
end

def content_for(key, &block)
  content_blocks[key.to_sym] = block
end

def yield_content(key)
  content_blocks[key.to_sym].call
end

def content_blocks
  @content_blocks ||= Hash.new
end
和模板:

<% #test.html.erb %>
<% content_for :style do %>
  style
<% end %>
<% content_for :body do %>
  body
<% end %>
<% content_for :script do %>
  script
<% end %>

风格
身体
剧本
当我打开irb进行测试时,我得到

irb(main):001:0> require './helper'
=> true
irb(main):002:0> render 'test.html.erb'
=> "\n\n\n"
irb(main):003:0> content_blocks
=> {:style=>#<Proc:0x005645a6de2b18@(erb):2>, :body=>#<Proc:0x005645a6de2aa0@(erb):5>, :script=>#<Proc:0x005645a6de2a28@(erb):8>}
irb(main):004:0> yield_content :script
=> "\n\n\n\n  script\n"
irb(main):005:0> yield_content :style
=> "\n\n\n\n  script\n\n  style\n"
irb(main):001:0>需要“/helper”
=>正确
irb(main):002:0>呈现“test.html.erb”
=>“\n\n\n”
irb(主):003:0>内容块
=>{:style=>#,:body=>#,:script=>#}
irb(主):004:0>产量内容:脚本
=>“\n\n\n\n脚本\n”
irb(主要):005:0>产量内容:风格
=>“\n\n\n脚本\n\n样式\n”
为什么
yield\u content:script
得到了
\n\n
的前缀,为什么
yield\u content:style
得到了
脚本\n\n
的结果。

如果你这样做了

ERB.new(File.read(path)).src
然后您可以看到erb将模板编译成什么。模板最终看起来像(为可读性而格式化)

其中,
\u erbout
是累积模板输出的缓冲区
\u erbout
只是一个局部变量,m


调用过程时,它们都只是附加到同一个缓冲区,该缓冲区已包含模板渲染的结果

谢谢你的回答。那么我如何才能使
产生内容:script
只输出
script
?不确定。也许可以从Rails的实现中获得一些灵感。好的,经过一些搜索,我终于做到了。只需通过将
render
函数更改为
ERB.new(File.read(path),nil,nil,“@exputf”).result(binding),使ERB将缓冲区存储在其他变量中,而不是
\erbout
。然后在
yield\u content
函数中,在调用Proc之前清除@extuf,就完成了。非常感谢您为我指明了正确的方向。如果有办法的话,您可能需要重置输出缓冲区,或者编写自己的包装器,通过观察该方法调用后添加到缓冲区的内容来处理此问题。
_erbout = ''
_erbout.concat "\n"
#test.html.erb
_erbout.concat "\n"
content_for :style do
  _erbout.concat "\n  style\n"
end