blocks in views

Hi --

This is more of an academic question, but I was wondering why the following doesn't work in a view:

<%= @items.each { |@item| render :partial => 'itemrow' } %>

Of course it can be done like this, which works:

<% for @item in @items %> <%= render :partial => 'itemrow' %> <% end %>

But I was curious as to why the first method doesn't work (at least it doesn't work for me). Is it not possible to use blocks in views?

What's happening is this:

<%= ... %> interpolates the string representation of whatever "..." evaluates to. In this case, "..." is a call to @items.each. The each method returns its receiver. So, in effect, what you're doing is:

   <%= @items.to_s %>

If you do the "for @item" one, or this:

   <% @items each do |@item| %>      <%= render :partial => "itemrow" %>    <% end %>

then you're interpolating the string representation of the rendering of the partial, zero or more times in succession. You could also do:

   <%= @items.map {|@item| render :partial => "itemrow" } %>

which would give you an array of all the rendered results. It's a little less straightforward, though, and depends on representing an array as a string, which is an unnecessary extra step. Mainly I mention it to illustrate the principle at work, which the difference between each and map shows you.

David