Short-Circuiting Conditionals and Ruby

Update: It has been pointed out to me, that my original understanding of the problem I was having in ruby was incorrect. Both sets of logical operators do short-circuit. The problem that I was having, and didn’t really illustrate in the examples, was caused by the fact that ‘or’ and ‘and’ have a lower precedence than ‘||’ and ‘&&’. Weird. Thanks Igal.

I often read blog entries about things that I think are very simple, or straight forward, or common knowledge; basically topics that I would never have imagined writing an entry about. I struggle to come up with blog entries sometimes, as it is evident by this blog.

I am developing a ruby on rails app as a side project, which I will write about here shortly, and came across a bug that stumped me, until I figured out that the ruby logical operators ‘or’ and ‘and’ do not short-circuit, but the operators ‘||’ and ‘&&’ do. “Ah ha, here is a topic I can blog about”, I thought to myself.

There are two basic logic operators that are used to construct conditional statements, OR and AND.

In order for a statement that uses OR to be true, only one of the operands needs to be true. Here is its truth table:

pq
TTT
TFT
FTT
FFF

The only time it is false is when both operands are false. The AND operator is the opposite, the only time it is true is when both operands are true, as you can see below.

pq
TTT
TFF
FTF
FFF

Without short circuiting, both operands are evaluated in order to determine the value of the statement. However one may be able to determine this value by just evaluating the first operand.

For example if the first operand of an OR statement is true, there is no need to evaluate the second operand because it doesn’t matter what the value of the second operand is. The whole statement is true, no matter what. Take a look at the truth table for OR above. Similarly for an AND statement, if the first operand evaluates to false, there is no way that the entire statement could be true, so again, the second operand does not need to be evaluated.

“Okay, so what?”, you may be thinking. “It speeds things up a little.” Yes, this is true, but it can be very useful. One of the common uses is to check if an object is null before calling a method. So for example, in ruby, the following statement will not give you an error if peole is nil.

if !people.nil? && people.size > 0
  #do something
end

However the following example will, when people is nil, because it is not short circuiting and it will call the method size on a nil varibale.

if !people.nil? and people.size > 0
  #do something
end

I am not sure if the moral of the story is to always use ‘||’ and ‘&&’, but I went back and made sure that all my conditioanls do because that is the way I think.

Tags:

,

Leave a Reply