I just came across a post from 2008 by Adam Loving where he points out a possible error in the way Ruby parses Boolean operators. From the post:
irb(main):001:0> x = false || true => true irb(main):002:0> x => true irb(main):003:0> z = false or true => true irb(main):004:0> z => false
Ruby parses the line 3 as:
(z = false) or true
Adam used Ruby 1.8.6. I’m using Ruby 1.9.2 and am seeing the same issue. It is not entirely unreasonable to assume that the two operators should behave the same way. So why does Ruby give || a higher precedence that ‘or’?
Well, it turns out that || and ‘or’ are not synonyms exactly and the reason is related more to linguistic semantics than computational logic. Check out the following two sentences taken from a blog post by prestonlee.com/.
- I’m either traveling by car or just staying home.
- I’m either traveling by car or by train.
In sentence 1, the semantics of ‘or’ is to describe the consequence of the first condition. Otherwise known as control flow. This is what the ‘or’ keyword is meant to represent. Indeed in Perl, a common idiom is:
do_something() or die "Something went wrong";
On the other hand, in sentence 2 the ‘or’ separates two arguments for which we are interested in their truth value. This is a more familiar case of wanting to test two conditions, ie what the first example was trying to do with z. Here’s how it should have been written not just because it produces the desired output, but because it is semantically correct as well.
z = false || true
If you’re interested in more complete explanation, below are the full links to the blogs which inspired this post. Special thanks to user rothsa in the #ruby IRC channel for pointing me in the right direction.