Why Doesn't "a" return true?


#1

Consider this code:

def a
  puts "A was evaluated!"
  return true
end

def b
  puts "B was also evaluated!"
  return true
end

puts a || b
puts "------"
puts a && b

This is the output:

A was evaluated!
true
------
A was evaluated!
B was also evaluated!
true
nil

A doesn't return true the second time? Why not?


#2

Hi @designslayer73591,

You have stumbled upon an interesting property of && and || which is called short circuiting . By this property, they tend to cut down on the number of the unnecessary calculations and provide efficiency. Let us see how:

Here's the truth table for ||:

  a   |   b   |  a || b
------------------------
 true |  true |  true
 true | false |  true
false |  true |  true
false | false |  true

As you can see, when a = true, it does not matter what the value of b may be - as the return value will be same - true - whether b is false or true. So, when you do: a || b, and a = true, then || will simply return true without evaluating b. Reread this again if this doesn't make sense.
It is only when a=false that b needs to be evaluated.

And here's the truth table for &&:

  a   |   b   |  a && b
------------------------
 true |  true |  true
 true | false |  false
false |  true |  false
false | false |  false

As you can see, when a = false, it does not matter what the value of b may be - as the return value will be same - false - whether b is false or true. So, when you do: a && b, and a = false, then && will simply return false without evaluating b. Reread this again if this doesn't make sense.
It is only when a=true that b needs to be evaluated.

Can you now reason why you have got the output the way you got it in the code? :wink:

Hope it helps!


#3

Ok ya I think that helps. So, a is not returning true to the console (at least not visibly) as it is not at the end of the method. But are still both being evaluated completely. Thanks!


#4

@designslayer73591 Are you asking that the second part of the output:

A was evaluated!
B was also evaluated!
true
nil

instead be this:

A was evaluated!
true
B was also evaluated!
true
nil

? Well, this is impossible. Indeed, A and B are both returning true. But by doing:

puts a && b

you are not printing the individual return value of the two methods, but only the return value of the && operator after it operates on the return value of a and b.

Hope it helps! :smiley:


#5

yes, that's perfect. Thank you!