Reputation: 33378
Is all equality in Ruby is "strict", analogous to ===
in PHP? I notice that there is a ===
operator in Ruby but it does something different.
Upvotes: 3
Views: 665
Reputation: 27793
===
is not an equality operator!
Not.
But, what is it?
You might be familiar with ===
as an equality operator in Javascript and PHP, but this just not an equality operator in Ruby and has fundamentally different semantics from other languages.
So what does ===
do?
===
is the pattern matching operator!
===
matches regular expressions===
checks range membership===
checks being instance of a class ===
calls lambda expressions===
sometimes checks equality, but mostly it does notSo how does this madness make sense?
Enumerable#grep
uses ===
internallycase when
statements use ===
internallyThat is why you can use regular expressions and classes and ranges and even lambda expressions in a case when
statement.
Some examples
case value
when /regexp/
# value matches this regexp
when 4..10
# value is in range
when MyClass
# value is an instance of class
when ->(value) { ... }
# lambda expression returns true
when a, b, c
# value matches one of a, b, c with `===`
when *array
# value matches an element in array with `===`
when x
# values is equal to x unless x is one of the above
end
All these example work with pattern === value
too, as well as with grep
method.
I can only guess why there's no !==
method but Tadman's intuition seems spot on, ===
is mostly used indirectly through case when
and grep
and thus likely didn't seem to need an explicit inverse operator. Most style guides for production code ban the use of ===
operator anyway.
If you are looking for other equality operators, check .eql?
and .equal?
Upvotes: 8
Reputation: 211670
Ruby doesn't need a strict ===
-type operator because the default comparator ==
is already quite strict, unlike PHP and others. It's not often the case any sort of conversion is done, so the cases where it is performed stand out as exceptional:
0 == ""
# => false
0 == "0"
# => false
"" == " "
# => false
0 == nil
# => false
0 == 0.0
# => true
In fact when you do use ===
you're often asking for trouble by being overly specific or inviting unexpected behaviour:
"" === String
# => false
String === ""
# => true
String === Object
# => false
Object === String
# => false
The meaning of ===
is defined by various classes in different ways to mean things often unrelated to "equality". It's just a shorthand like <<
is at times. Object === String
is actually Object.===(String)
which is why it produces different results from String.===(Object)
. In that case it means "is equal to or a derived class of...".
It's because of this relative rarity that !==
doesn't really need to exist in the first place. ===
is often used only indirectly, as it's the default method for comparing things via a case
statement.
Upvotes: 3
Reputation: 7308
Ruby's equality is not strict using ==
, at least not like ===
in JavaScript. Ruby has stricter equality methods, such as eql?
and equal?
, but the ===
is not for strict equality. The ===
method is called the subsumption operator. It's most used implicitly in case
statements. This is to say that
case a
when b ...
when c ...
else ...
end
is equivalent to
if b === a
...
elsif c === a
...
else
...
end
Having said that, !==
could exist, but instead it is just left for the user to do !(a === b)
. Note that ===
is not commutative as in a === b
is not the same as b === a
.
Upvotes: 1
Reputation: 33378
Ah... after digging deeper I think I answered my own question. Ruby has .eql?
.equal?
link
Upvotes: 1