Equality means that two things are the same. In Ruby, we compare objects & their values to find out if they’re the same object.
The question is…
How do you compare two things in Ruby?
Like this:
1 == 1 # true
You’re probably familiar with this already…
But did you know that ==
is a method & not just syntax?
The implications are big.
You can implement this method in your own classes to make them more powerful. And that’s what you’ll learn about in this post!
What Makes Two Objects The Same?
You can compare two strings like this:
"foo" == "foo"
If the words & characters are the same, then they’re equal.
The expression returns true
.
This works because the String
class implements a ==
(two equal signs) method that knows how to compare strings.
But what if String
didn’t implement ==
?
Then Ruby would use Object
‘s implementation of ==
, which defaults to testing for object identity, instead of object contents.
Example:
Object.new == Object.new # false String.new == String.new # true
The reason Object
returns false
is because two new objects have different object id’s.
In the case of String
, since it compares based on contents, and two new strings have the same content (they are empty) it returns true
.
Implementing Equality
Now let’s use what you just learned to make your own classes more powerful by being able to compare them.
Thanks to the ==
method…
You can define exactly what it means for two instances of your own class to be equal.
Example:
class Product attr_reader :name, :price def initialize(name, price) @name, @price = name, price end def ==(other) self.name == other.name && self.price == other.price end end p1 = Product.new('book', 49) p2 = Product.new('book', 49) p1 == p2 # true
The ==
method says that both the name and the price must be the same for two Product
objects to be considered equal.
Remember:
If you don’t implement this method (or use the Comparable
module, which I explain in my Ruby book) the two objects will be compared using their object id’s, instead of their values.
Also I should mention that if you use a Struct it already implements ==
for you.
What About Triple Equals?
You may be wondering if ==
is a method, is ===
also a method? And the answer is yes 🙂
So what’s the difference between the two?
In Javascript there is a clear difference, where ==
will try to convert the object types to be the same if they aren’t (1
vs '1'
). And ===
is for ‘strict’ equality.
But in Ruby there is not such thing. What ===
means depends on the class implementing it.
In many cases it is just an alias for ==
.
Like in String
and Object
.
Here’s a table of built-in classes which give ===
a special meaning:
Class | Meaning |
---|---|
Range | Returns true if obj is an element of the range, false otherwise. |
Regexp | Match regexp against a string. |
Module | Returns true if obj is an instance of mod or and instance of one of mod’s descendants. |
Proc | Invokes the block with obj as the proc’s parameter like Proc#call . It is to allow a proc object to be a target of a when clause in a case statement. |
Conclusion
In this post you learned how to make your classes more powerful by implementing the ==
method. You also learned the difference between ==
and ===
.
Don’t forget to share this post so more people can see it 🙂