Everything is “Comparable” in Ruby

Merdan Durdiyev
kode-art
Published in
3 min readAug 11, 2021

Welcome 😉

Hello dear friends, coders, enthusiasts, and guests. You might have noticed a couple of emojis I used in headers. I found out about this feature just recently and was happy to give it a try 😃.

Everyone is welcome to spend a bit of their precious time to learn a tiny bit of something about precious Ruby. And today, we are going to take a look at the “Comparable” module in Ruby. Here we go…

What is the “Comparable” module in Ruby?

The Comparable mixin is used by classes whose objects may be ordered and it is part of the Ruby core. It includes a bunch of methods used for object comparison purposes.

For example, the Numeric and String classes include this mixin. To check that, we can use the “ancestors” method that lists the classes in the ancestor tree of the current class.

irb> Numeric.ancestors
=> [Numeric, Comparable, Object, Kernel, BasicObject]
irb> String.ancestors
=> [String, Comparable, Object, Kernel, BasicObject]

The class must be defined using an operator which compares the receiver against another object.

The “Comparable” module uses “<=>” (Rocketship operator) to implement the conventional comparison operators (<, <=, ==, >=, and >) and the method between?

So now, let’s get to the implementation details and try to use them in a user-defined class.

How do we use it?

To use that module and its features in another class, we have to mix that module in our class and define the “<=>” (Rocketship ) method and the method “between?”. This method should return only 3 different values based on the comparison we are making in that specific class. It should return “1”, “-1” or “0”.

It will return -1, 0, and 1 depending upon the receiver.

  • -1 : If the receiver is less than the other object,
  • 0 : if the receiver is equal to the other object,
  • 1 : If the receiver is greater than the other object.

Now, let’s try to use it in a user-defined class and compare the class instances.

# defining class
class Box
# include comparable module
include Comparable
attr :weight def <=>(other_box)
weight <=> other_box.weight
end
def initialize(weight)
@weight = weight
end
end# creating objects
box_1 = Box.new(16)
box_2 = Box.new(34)
# using < operator
p box_1 < box_2 # true
# using <= operator
p box_1 <= box_2 # true
# using == operator
p box_1 == box_2 # false
# using >= operator
p box_1 >= box_2 # false
# using > operator
p box_1 > box_2 # false
# using "between?" method
p box_1.between?(10, 20) # true
p box_2.between?(10, 20) # false

And that’s it. By just mixing in the “Comparable” module and defining the “Rocketship” method in our new class, we gain the ability to compare and therefore, sort objects.

In the example above, we defined a delivery box class that is compared by its weight. That means, we can compare boxes using any of (<, <=, ==, >=, and >) operators and the between? method.

Yes, it is that easy!

Conclusion 👋

We’ve come to the end of the article and now we know a little more about Ruby. Now, we definitely can compare and sort things using Ruby, that were non-comparable before. And the simplicity of its implementation confirms the words of Matz once again.

“I hope to see Ruby help every programmer in the world to be productive, and to enjoy programming, and to be happy. That is the primary purpose of Ruby language.”

Yukihiro Matsumoto

A way to go, my friend. The “Comparable” mixin. A tiny block that gives huge possibilities. The companion mixin for this is the “Enumerable” mixin. That’s the next article topic.

Stay healthy, wealthy, and wise. Learn, practice, and rise. 💪

--

--