fleshyorgans

tryin’ not to be a linux fanboy

fleshyorgans Two Cats

Ruby Braces vs. Do/End blocks

July 23rd, 2007 · 1 Comment

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.

Tags:

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