Topic: Simple preference or actual benefit?

Hello,

These two pieces of view code do the same thing. I find the first personally more "readable"

<% for category in @categories %>
  <h2><%=h category.title %></h2>
  <ul>
    <% for link in category.links %>
      <li><%=link_to link.title, link.url %></li>
    <% end %>
  </ul>
<% end %>

However, I get the feeling that the code below is considered more the "standard". I get this sense because the scaffolding generators in Rails 2.3 create code in the same manner.

<% @categories.each do |category|
  <h2><%=h category.title %></h2>
  <ul>
    <% category.links.each do |link| %>
      <li><%=link_to link.title, link.url %></li>
    <% end %>
  </ul>
<% end %>

Is there any true additional benefit to the second approach, or is it purely a preference issue? Thanks in advance.

Re: Simple preference or actual benefit?

Some reasons why i think the 'each' approach is better.

1) Other classes such as Hash have an each method as well.  So, you can do this with a hash for example.

hash = {:one => "bun", :two => "shoe"}

hash.each do |key, value|
  puts "#{key} points to #{value}"
end

So, it sort of trains you for the more general case of calling 'each' on any class, rather than an array.

2) Another reason is that 'each' is the 'real' method and the 'for' approach is just synactic sugar added for people who are used to for loops.  It's doesn't really make any difference though.

3) Personally, i always use the each approach.  One thing i like is that it sticks the local loop variable right out at the end in the pipes, so it's really obvious.  The syntax of the whole thing makes it very obvious that there's some looping going on. 

4) Another reason is that it's more in keeping with what happens in ruby generally, which is you call a method on an object (that's pretty much all that ever happens).  If you see this:

for category in @categories

and you're not familiar with the syntax, it's not really obvious what's happening.  What's the object that's being called - "category" or "@categories".  What's the method being called - "for" or "in"?  it's not really clear.

Whereas if you see this

@categories.each

you think "so, we're calling a method called 'each' on the array - what does that do?" and then you can go and look the 'each' method up in the api.  It's just more in keeping with the language.

5) It's more conventional.  Sticking to conventions makes it easier for other people (and yourself in the future) to read your code. 

I think this laast point is the closest to being an actual benefit - there's no benefits in terms of performance though.

Last edited by Max Williams (2009-06-01 10:41:44)

###########################################
#If i've helped you then please recommend me at Working With Rails:
#http://www.workingwithrails.com/person/ … i-williams

Re: Simple preference or actual benefit?

In Ruby 1.8.x the first is faster, but since 1.9 the speed is the same.

The second demonstrates more the fact that you are using a code block which is very important in Ruby, so I prefer to use the second.

Re: Simple preference or actual benefit?

Actually, there's a subtle difference between :each and :for (well, at least one I can remember). Any local variables defined inside the :for block will be accessible after the block, which is not the case with :each.

Either way, I never use :for, and personally feel it should be removed from the language.

Edit: Also thought I'd remind you that if you are using Ruby 1.8.x, the name of the block variable you use is important, as it will rewrite any existing variable with that name, which could cause unexpected results. This is fixed in Ruby 1.9+ I believe, here's an example of what I mean

i = 10
[1,2,3].each do | i |
  puts i
end

puts i

Results in:
1
2
3
3


Obviously, you would expect :i to be 10. The same result can be observed if you use :for.

Last edited by Ninju (2009-06-01 11:15:58)

If I've helped you out with something, feel free to recommend me on working with rails.

Re: Simple preference or actual benefit?

Thanks to all for the great input. Very helpful and much appreciated.