3

Why does nil && false return nil while false && nil returns false?

I read the top answer in nil || false and false || nil in ruby. It seems to me that both nil and false evaluate as falsy value, but why do these two expressions return different values?

Community
  • 1
  • 1
Zzz
  • 1,703
  • 1
  • 14
  • 21
  • 3
    Try this: `false && 1.0/0 #=> false; nil && { 1=>2 }.quick_brown_fox #=> nil` (where no method `quick_brown_fox` has been defined). Ruby returns the first value if it is `false` or `nil` (logically false, "falsy"), and does *not* evaluate the expression following `&&`. The latter is especially important as often one writes an expression where the part following `&&` is a valid Ruby statement only when the part to the left of `&&` is logically true ("truthy"). For example, `obj.is_a?(Hash) && obj[:cat]`, where `obj` might be, say, an array, integer or hash. – Cary Swoveland Jan 20 '17 at 07:49
  • _"Specs fail in 4.2 version but not 4.1"_ – must be something else. Ruby's evaluation strategy hasn't changed and Rails does not and can not alter it. – Stefan Jan 20 '17 at 09:06

2 Answers2

10

The rule is simple: && returns its first argument if it is falsy. Otherwise, it evaluate and returns its second argument.

So in

nil && false

and

false && nil

In both cases, the first argument is falsy. (nil and false are the only two values that evaluate falsy), so the result of the expression is the first argument.

The fact that the second argument also happens to be false doesn't matter. In fact, the second argument isn't evaluated because of short-circuit.

spickermann
  • 100,941
  • 9
  • 101
  • 131
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
-1

It's about operations order. Nil doesn't have a boolean value. In && statement it returns false when at least on argument is false.

So in the expression: false && nil it is discovering that the first argument is false and there is pointless to check the second one, so it returned false. In second case - nil && false it encounters nil, so the value which cannot be compare with boolean, in consequence the expression cannot be evaluated, so it returns 'nil', like in every other similar case in ruby.

In '||' statement it gives false where first or second argument is false.

1st case: false || nil - it checks that first argument is false and then verifies second one which actually is nothing, so that it gives first value.

2nd case nil || false it checks first is nothing, then second which is boolean so it returns false.

  • 1
    Every object has a boolean value in Ruby: `false` and `nil` are _falsey_, all other objects are _truthy_. – Stefan Jan 20 '17 at 08:31