Jamie's Blog

Ruby developer. CTO. Swimmer. Always trying to write more

Sneaky Ruby tricks me again (and and && and or or ||)

You see, I had this little piece of code like:

if last_statistic.blank? or last_statistic.different?(options)
  # do stuff

but I wanted to make it a bit more obvious what that condition represented so I changed it to

create_new = last_statistic.blank? or last_statistic.different?(options)
if create_new
  # do stuff

That should be the same, right? Right?!


I am not one for rote learning, which is my excuse for not knowing the exact operator precedence rules in Ruby. I knew that and and && (or or and ||) were not the same (have fun parsing that sentence!).

Here’s the basic rule: never use and or or with an assignment

I knew this but I got tricked into it by the simple refactoring.


Because = has a higher precedence than and or or. So

create_new = last_statistic.blank? or last_statistic.different?(options)

is actually being executed as

(create_new = last_statistic.blank?) or last_statistic.different?(options)

It also explains why the value seemed to be correct when I pasted the condition into a Pry session (because I wasn’t including the assignment).

I think every has this moment of WTF but I consider and and or to be an invaluable part of Ruby’s literacy. This is just my little reminder to myself to use the word-y operators with care