Chay Huan
Chay Huan

Reputation: 123

Why isn't 'false' equal to 'nil'?

false is not equal to nil, for example:

false == nil # => false

The same goes for false and 0:

false == 0 # => false

You get the same result for nil and 0:

nil == 0 # => false

Why does Ruby act like this?

Upvotes: 0

Views: 859

Answers (2)

Todd A. Jacobs
Todd A. Jacobs

Reputation: 84343

Nil and False (Equality)

Despite what many people new to the language may expect, nil and false are objects rather than language keywords. Consider FalseClass which says:

The global value false is the only instance of class FalseClass and represents a logically false value in boolean expressions.

Likewise, NilClass is:

[t]he class of the singleton object nil.

When you use a method like Comparable#== to compare them, Ruby invokes the spaceship operator <=> on the instances since neither class defines the #== method. Because nil and false are not the same objects, and because neither overrides the basic equality operator, the expression false == nil will always be false.

Likewise, an Integer like 0 is neither an instance of FalseClass nor NilClass. Both false == 0 and nil == 0 are therefore also false because neither instance evaluates to zero.

Truthy and Falsey (Conditionals)

For branching purposes, both false and nil evaluate as false in a conditional expression. Everything else evaluates as true.

Consider the following non-idiomatic, contrived, but hopefully illustrative example of Ruby's basic truth tables:

def truth_table value
  if value
    true
  else
    false
  end
end

truth_table nil
#=> false

truth_table false
#=> false

truth_table true
#=> true

truth_table 'a'
#=> true

truth_table 0
#=> true

truth_table 1
#=> true

Boolean Evaluation

Nil and false are semantically different in Ruby, and descend from different base classes. They are also not equal to each other. However, they can both be treated as "not true" for branching purposes or within a Boolean context. For example, consider the following idioms for casting a result as a Boolean true or false value:

!(nil)
#=> true

!!(nil)
#=> false

You can use this idiom to shorten the previous truth table example to:

# Convert any value to a Boolean.
def truth_table value
  !!value
end

# Test our truth table again in a more compact but less readable way.
table = {}
[nil, false, true, 'a', 0, 1].map { |v| table[v] = truth_table(v) }; table
#=> {nil=>false, false=>false, true=>true, "a"=>true, 0=>true, 1=>true}

Upvotes: 3

alexisdevarennes
alexisdevarennes

Reputation: 5632

In Ruby, the only time nil will return true on a == comparison is when you do: nil == nil

You can read more about nil here:

https://ruby-doc.org/core-2.2.3/NilClass.html

nil is the equivalent of undefined in JavaScript or None in Python

Consider in JavaScript:

>> (undefined === false)
=> false

Or Python:

>> (None == False)
=> False

Upvotes: 5

Related Questions