Beware! (Or, why I finally started paranthesizing method arguments in Ruby)

I was tripped up by a seemingly innocuous piece of code today. Here was the form of it:

foo = {}
puts foo['bar'] or 'bar'

=> nil #!

I expected to see ‘bar’, but instead I got nothing. After some head scratching, I tried:

foo = {}
puts foo['bar'] || 'bar'

=> foo # that's more like it

Long story short, these two forms of the ‘or’ operator behave differently here because they differ greatly in precedence. Due to the difference in precedence, they bind differently:

puts(foo['bar']) or 'bar'

puts(foo['bar'] || 'bar')

That’s the last straw for me. I’ve always preferred leaving out parantheses whenever possible, and up until now, have considered the comfortable readability to be a win over any possible ambiguity. Precendence wierdness like this is too subtle though.