In Ruby, why does a equality with nil ("Date.new == nil") return nil? In Ruby, why does a equality with nil ("Date.new == nil") return nil? ruby ruby

In Ruby, why does a equality with nil ("Date.new == nil") return nil?


I checked the source and here's what I found out:

The comparison operators defined by Comparable all use the function rb_cmpint together with <=>. rb_cmpint raises an exception when one of the operands is nil.

So the operators of Comparable raise an exception if the rhs is not comparable to the lhs. I.e. 5 < 2 is false, but 5 < "la" raises an exception. They do this to differentiate between cases where < is not true because the rhs is smaller and cases where it's not true because the rhs is not comparable. Or in other words: When x < y is false that implies that x >= y is true. So in cases where that would not be the case, it throws an exception.

== raising an exception would be bad, because == usually does not (and should not) require its operands to be comparable. However == uses the same method as the other operands, which does raise an exception. So the whole function is simply wrapped in an rb_rescue. And that returns nil if an exception is thrown.

Note that this only applies to ruby 1.8. This has been fixed in 1.9 and now == never returns nil (except of course if you define your own == that does).


If you're depending on this for code, you can always use the .nil? method which any Ruby Object responds to.

>> Date.new.nil?=> false


The Date class includes the Comparable#== method, but that method invokes the <=> method of the receiver. In this case that's Date#<=>, which expects another Date object. When it receives nil it returns nil. This behavior certainly seems inconsistent, and I don't know the reasons behind it.