Ruby Style: Ruby do ... end versus {}
I’m lucky enough to be pairing with Jim Weirich and I’m learning a ton. Of course I’m learning things like how to get the most out of the one true editor and the really hard to understand ins and outs of Ruby.
What I’m enjoying the most is the different perspective on developing in Ruby. We’ve had quite a few discussions about style. The most recent I thought I would put up here.
One or more lines
When you come to Ruby people inevitably ask the question of when to use do … end and when to use the {} syntax for blocks. The normal answer, and the one I’ve subscribed to, is that you use {} if you are on one line, and do … end if you span more than one line.
Items.find(:all).each { |item| puts item.description }
Items.find(:all).each do |item|
# do something
# do something else
item.save
end
Problems with this approach
First, when you decide to add more functionality into your block, you have to change the surrounding syntax. If you are following Red, Green Refactor, this could happen quite frequently.
The most interesting issue we discussed was that this style tells you nothing of value when you are reading the code. We can tell visually that it’s one or two lines.
Use {} when returning a value, do … end when performing actions
The alternative is to use these two syntaxes to communicate what you are doing. Jim’s style of development, which I’m quickly growing more fond of, is to use {} when you are returning a value from a block.
[1,3,4,5,6].find { |i| i == 4 }
[1,3,4,5,6].collect { |i| i.to_s }
On the flip side use the do … end syntax when performing actions, but not returning any values.
%w{ one two three four five }.each do |i| i.capitalize! end
%w{ one two three four five }.each do |i|
i.capitalize!
i.reverse!
end
So now when you are glancing through some code and you see a block that looks like this:
array.method_accepting_block { |item|
some_action
more_actions
}
you will know that they are returning a value at a glance.
Interesting idea. Thoughts?



Joe, I am still mystified why the end…do exists at all as it grates against the other terseness facilities of Ruby, but then so does the underscored variable names convention (as opposed to lowCamelCased ones).
As for using {} only when returning a value, doesn’t every statement return a value (in your example, the array with it’s elements capitalised and reversed)?