How to Compare Two Objects in Ruby By Implementing Equality

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 🙂