Wednesday, July 7, 2010

Ruby Operator Precedence

Ruby is about simplicity and clarity, but if you don't understand operator precedence, and think that "||" is the same as "or", it will eventually bite you.

Take for example the case of an orange:

class Orange
 def sweet?
   true
 end

 def sour?
   false
 end
end
Very simple, right? You can do things such as:
orange = Orange.new
puts "This orange is sweet" if orange.sweet?
puts "This orange not sour" unless orange.sour?
But, lets try to make a method to test whether an orange is sweet or sour.
def sweet_or_sour(orange)
 answer = orange.sour? or orange.sweet?
 puts "The orange is either sweet or sour: #{answer}"
end
Now call it:
orange = Orange.new
sweet_or_sour(orange)
What? The answer should be true! Why did this happen?

The answer is that the "or" has lower precedence than the assignment operator "=". The same is true for "and" vs. "&&" ("and" has lower precedence than "="). "not" is also lower precedence than "=", but "not" is higher than "or" or "and".

For more info, see Table 18.4 of The Pragmatic Programmer's Guide to Programming Ruby.

No comments: