How do you compare two things in Ruby?
== as you already know… but did you know that
== is a method & not just syntax?
You can implement this method in your own classes to make them more powerful. And that’s what I want to talk about in this post.
As you know you can compare two strings like this:
"foo" == "foo"
And if the content is equal then this will evaluate to true. This works because the
String class implements a
== 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.
Object.new == Object.new # false String.new == String.new # true
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
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.
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
== method says that both the name and the price must be the same for two
Product objects to be considered equal.
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.
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?
== will try to convert the object types to be the same if they aren’t (
=== 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
Here’s a table of built-in classes which give
=== a special 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
In this post you learned how to make your classes more powerful by implementing the
== method. You also learned the difference between
Don’t forget to share this post so more people can see it 🙂