Uh! Are you a cat?!

In this article, we’re going to explore the following topics:

eql? vs == vs ===

vs vs The equal? method

Before to start

I’m thrilled to share with you our latest project: Fun Facts about Ruby — Volume 1

Please feel free to spread the word and share this post! 🙏

Thank you for your time!

eql? vs == vs ===

In Ruby, as any classes inherit directly (or not) from the Object class, then the object equality logic is implemented between the Kernel module and the BasicObject class.

This allows us to check the equality of two objects without effort

Here, we can see that the BasicObject#== , Kernel#=== and Kernel#eql? methods share the same logic.

Indeed, these 3 methods actually refer to the same C function behind the scene.

Feel free to have a look at the Ruby Object Model article if you’re not familiar with this ancestor chain and the Object class in Ruby.

So what’s the difference between them?

The difference between these 3 methods is at a semantic level.

The Kernel#=== method

This method is used to check equality in case statements.

So the class that overrides this method should provide meaningful semantics for this purpose.

Feel free to have a look at the String class documentation to see how the Object#=== is overridden in this class.

The BasicObject#== method

This method is overridden in most of the Core classes in Ruby.

The particularity of this method is that it’s more permissive for object comparison.

For example, the Integer class overrides this method to compare if objects are numerically equal

Here, 1 equals 1.0 numerically.

And this, despite the fact that the first object is an Integer and the second one a Float .

So when you want to check equality of 2 objects depending on their values and not their types, then override the Kernel#== .

The Kernel#eql? method

This method tests object equality by checking if the 2 objects refer to the same hash key.

This type of comparison is used in Hash instances to determine the uniqueness of a member

Here, the instances assigned to the key and other_key variables are 2 distinct instances.

Now, if the Hash#[]= method made the comparison at an object-level then it’d rather create an entry for each string.

So we’d have h # => { 'key' => 'key', 'key' => 'other key' } .

But fortunately, it uses the #eql? method.

When overridden, this method bases equality comparison on the value returned by the hash method.

The hash method returns an Integer .

This value is the same for two identical objects.

As our two instances are identical in term of values then they share the same hash .

This means that h overrides the value contained in the entry h['key'] instead of adding a new entry.

The equal? method

The BasicObject#equal? method is used to verify object identity.

It verifies if a is literally the same object as b .

So it’s not recommended to override this method.

Indeed, as the == , === and eql? methods are designed to be overridden in specialisations of the Object class, then the only method to check object equality at an object ID level is equal? .

Voilà!

ONE MORE THING ⬇

Feel free to subscribe here: www.rubycademy.com