DEV Community

Cover image for Make Your Ruby Classes More Powerful by Implementing Equality
Jesus Castello
Jesus Castello

Posted on • Updated on

Make Your Ruby Classes More Powerful by Implementing Equality

This post was originally published on rubyguides.com

How do you compare two things in Ruby? Using == 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.

Equality Basics

As you know you can compare two strings like this:

"foo" == "foo"
Enter fullscreen mode Exit fullscreen mode

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.

Example:

Object.new == Object.new # false
String.new == String.new # true
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 ===.

If you enjoyed this post check out my blog here & sign-up to my newsletter :)

Top comments (0)