My years of programming have taking me along the lines of
learning Java in college, to PHP as a CMS hacker and now to Ruby. I was
recently going through an exercise in
Exercism.io and while somebody was
“nitpicking” my code, they mentioned that I probably didn’t need the
=== in my
code. My code was making sure two variables were of the same type and
value. It looked a little like this:
``` ruby # Bad - my original code variableA === variableB
Good - my new code
variableA == variableB ```
My nitpicker mentioned that I only needed
==. But since I came from
the recent world of PHP, I was confused why I shouldn’t use
PHP, the double equals just checks for the same value and disregards
type. In Ruby, it’s a whole different story.
I discovered it had to do with the fact that everything in Ruby is an
object and different objects can have different definitions for equality
(same goes for all object orient languages). Ruby’s Object class has
.eql? by default. Many times Ruby classes override
.equal? should never be overriden.
What is the ‘==’?
At the Ruby Object level,
== returns true only if the two compared
entities are the same object. Typically this is overriden in descendant
classes. You’ll want to use this method if your object implements this.
If you are looking for generic equality,
.eql?. You should look at your particular Ruby
object in question to see how they implemented
What is the ‘===’?
=== is the Case Equality Operator (Case Subsumption Operator)
The best answer I found was the Subsumption Operator answers the question, “If I have a drawer labeled ‘a’ would it make sense to put ‘b’ in that drawer?”
``` (1..5) === 3 # => true (1..5) === 6 # => false
Integer === 42 # => true Integer === ‘fourtytwo’ # => false ```
What is the ‘.eql?’
A good synonym phrase would be ‘Generic Equality’. The eql? method returns true if obj and other have the same value.
.eql? method returns
true if both objects in question return the
same hash key. This is used by Hash to test members for equality. For objects of class Object,
eql? is synonymous with ==.
Subclasses normally continue this tradition, but there are exceptions. Numeric types, for example, perform type conversion across ==, but not across eql?, so:
1 == 1.0 #=> true
1.eql? 1.0 #=> false
The Ruby Documentation explains
At the Object level,
==returns true only if obj and other are the same object. Typically, this method is overridden in descendant classes to provide class-specific meaning.
What is the ‘.equal?’ - determines object identitfy
This is effectively pointer comparison. “Is this the exact same object?”
Equality in Ruby is confusing. You’ll want to be informed when using it and make sure you have an effective test suite.
== is overriden on a per class basis. Usually you’ll
want to use the class’s implementation of equals.
=== answers the question “If I have a drawer labeled ‘a’, would it
make sense to put ‘b’ in that drawer?”. You don’t use this as often.
.equal? should never be overriden by a subclass.
``` a = “a” # => “a” other = a.dup # => “a”
a == other # => true a === other # => true a.eql? other # => true a.equal? other # => false ```