0

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?

4
  • 7
    why would False == nil? are apples == oranges? Commented Nov 15, 2017 at 23:46
  • 4
    Doesn't seem weird to me. They're different types of things. You'll find the same kind of thing in other languages. Try False == None in Python or false == null in JavaScript. In Python False == 0, but that's a quirk if you ask me. And in JavaScript, null == undefined, but that's pretty bizarre IMO. When things of different types are considered equal, that leads to all kinds of headaches, which is why it's recommended to use === in JS for example. Commented Nov 15, 2017 at 23:50
  • 3
    Ruby isn't acting weird. It's per the spec. I think the expectations of what is "normal" is what's unwarranted. In Ruby, all values evaluate to truthy except for FALSE and nil which evaluate to falsey. (All of the comparisons shown in the question evaluate to false, and that is the behavior we expect, because that's whats documented in the language specification. Commented Nov 15, 2017 at 23:50
  • 3
    Your question is unclear. fase == 0 is false, because false and 0 are not equal. They are completely different things that have absolutely nothing whatsoever to do with each other. Why would they be equal? It would help if you explain why you explain they should be equal, otherwise the simple answer to your question is just: "because they aren't equal, and anything else just makes no sense". Commented Nov 16, 2017 at 6:30

2 Answers 2

5

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 
Sign up to request clarification or add additional context in comments.

9 Comments

@ChayHuan Glad I could help. Please consider marking the answer as correct.
Updated :) Thank you very much!
Thank you for caring about our future sentient NLP engines in their attempts to learn Ruby!
I guess we'll have to wait and see. Others may point out something new or provide a different explanation which may or may not be clearer. My previous comment is by no means a slight on your answer.
Pedantry: Your JavaScript example would be better with === as == can do some surprising conversions. And careful with null in SQL, null = null is not true in SQL so SQL's null isn't quite the same as Ruby's nil.
|
3

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} 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.