简体   繁体   English

如何从Ruby块中的多个语句产生结果?

[英]How do I yield results from multiple statements in a Ruby block?

I have a pair of Rails helpers, one of which is meant to accept a block and the other of which just renders a button. 我有一对Rails助手,其中一个是用来接受一个块的,另一个是用来渲染按钮的。 Here are simplified versions the helper definitions: 这是帮助程序定义的简化版本:

def nav_wrapper(nav_at, id, css_class, &block)
  "<ul class="complicated">\n #{yield} \n</ul>".html_safe
end

def nav_btn(nav_at, caption, id = caption.downcase.dasherize)
  "Nav button codes goes here".html_safe
end

I'm trying to set things up such that I can do something like this: 我正在尝试进行设置,以便可以执行以下操作:

<%= nav_wrapper(@nav_at, "Top Nav", "class") do %>
  <%= nav_btn(@nav_at, "Foo", "id") %>
  <%= nav_btn(@nav_at, "Bar", "id") %>
  <%= nav_wrapper(@nav_at, "Sub Nav", "class") do %>
    <%= nav_btn(@nav_at, "SubFoo", "id") %>
    <%= nav_btn(@nav_at, "SubBar", "id") %>
  <% end %>
<% end %>

But, the yield in the nav_wrapper method only picks up the last statement of each block. 但是,该yieldnav_wrapper方法只挑选了每个块的最后一条语句。 So in this example, I get the Top Nav wrapper, Foo and Bar are skipped, I get the Sub Nav wrapper (being the last statement in the outer nav_wrapper block), SubFoo is skipped, and I get SubBar (being the last statement in the inner nav_wrapper block). 所以在这个例子中,我得到了Top Nav包装器,Foo和Bar被跳过,Sub Nav包装器(在外部nav_wrapper块中的最后一条语句),SubFoo被跳过,SubBar(在内部nav_wrapper块)。

I know that the reason for this behavior is that the block of code is implicitly returning the last evaluated value, but I know there are lots of template helpers that render all the interstitial lines ( form_for , for example). 我知道发生这种情况的原因是代码块隐式返回了最后一个求值,但是我知道有很多模板助手可以渲染所有插页式广告行(例如, form_for )。 Can someone help me figure out what the magic trick is here? 有人可以帮我弄清楚这里的魔术吗?

When a ERB template is compiled, it is converted to code which adds strings to a buffer. 编译ERB模板时,它将转换为将字符串添加到缓冲区的代码。 (Look at the source code for ERB to see what I mean.) Methods from Action View like form_for execute the block, and then retrieve the text in the ERB buffer. (查看ERB的源代码以了解我的意思。)动作视图中的方法(如form_for执行该块,然后在ERB缓冲区中检索文本。

Open up the lib/ruby/1.9.1/gems/1.9.1 folder, and look for actionpack. 打开lib/ruby/1.9.1/gems/1.9.1文件夹,然后查找actionpack。 Open up whatever version of Action Pack you have, and go to lib/action_view/helpers/capture_helper.rb . 打开任何版本的Action Pack,然后转到lib/action_view/helpers/capture_helper.rb There is a method in there called capture , which is used by form_for to execute a block and retrieve the text generated by ERB. 那里有一个叫做capture的方法, form_for使用它来执行一个块并检索ERB生成的文本。

If you are writing a Rails helper, then presumably capture will be available to your code. 如果您正在编写Rails助手,那么大概capture将可用于您的代码。 If not, try include ActionView::Helpers::CaptureHelper . 如果不是,请尝试include ActionView::Helpers::CaptureHelper

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM