When parentheses are important:
So, braces have higher precedence over do/end blocks. According to Pickaxe, when calling a method with no parentheses, the braces will be applied to the last method parameter, do will be applied to the invocation.
A Very Contrived Example:
def string_to_integer
if block_given?
yield.to_i
else
0
end
end
a = [1,2,3]
A) a.inject string_to_integer { ‘5′ } do |i,sum| i + sum end => 11
B) a.inject string_to_integer { |i,sum| i + sum } => undefined method error
C) a.inject string_to_integer do |i,sum| i + sum end => 6
in A, the first brace is sent to the string_to_integer method
in B, the same happens, but the block was actually meant for inject
in C it works as intended.
Just food for thought.

1 response so far ↓
1 Zoran Rilak // Aug 1, 2007 at 5:26 pm
Good point, Jonathan. I stumbled upon this when writing tests for my methods. I was aware that do…end differed from {} in the order of precedence, but never gave it a thought until I did this:
assert_raise ArgumentError { doodledoo(’wrong’, ‘args’) }
I was indeed getting an exception, but not the one I was hoping for. Of course, the proper way to write this would be
assert_raise(ArgumentError) { doodledoo(’wrong’, ‘args’) }
or, as a matter of preference,
assert_raise ArgumentError do doodledoo(’wrong’, ‘args’); end
From the legibility standpoint, braces win. This just goes to show that sloppy coding should be discouraged even in tests (perhaps more so in tests!)
Leave a Comment