How to Define Custom Comparison Logic for "<=>" Operator in Ruby?

You can define custom comparison logic for the spaceship operator (<=>) in a Ruby class by implementing the "<=>" method, like so:

class CustomObject
  def <=>(other)
    # ...
  end
end

This will override the default behavior of the <=> operator for objects of that class. The return value of this method determines the order of the objects, which should be one of the following, depending on how the current object compares to the "other" object of the same class:

  1. -1 — if the current object is "less than" the other object;
  2. 0 — if both objects are "equal";
  3. 1 — if the current object is "greater than" the other object.

For example, consider the <=> method implementation in the following custom "Person" class:

class Person
  attr_accessor :name, :age

  def initialize(name, age)
    @name = name
    @age = age
  end

  def <=>(other)
    # compare by age first
    age_comparison = age <=> other.age

    if age_comparison == 0
      # if ages are equal, compare by name
      return name <=> other.name
    end

    return age_comparison
  end
end

# ...

Here, the <=> method first compares people by their ages. If the ages are equal, it proceeds to compare them by their names in lexicographical order. The following demonstrates how the comparison would look like for objects of this class:

# ...

person1 = Person.new('Alice', 30)
person2 = Person.new('Bob', 25)
person3 = Person.new('Carol', 30)

puts person1 <=> person2 #=> 1 (`person1` is older than `person2`)
puts person1 <=> person3 #=> -1 (same age, but "Alice" < "Carol" lexicographically)
puts person2 <=> person3 #=> -1 (`person2` is younger than `person3`)

In this way, you can sort an array of Person objects by both age and name, with age taking precedence in the comparison:

# ...

people = [person1, person2, person3]
sorted_people = people.sort

print sorted_people
#=> [#<Person @name="Bob", @age=25>, #<Person @name="Alice", @age=30>, #<Person @name="Carol", @age=30>]

In the example above, the array of people is sorted in ascending order as per the defined comparison logic in the <=> method of the Person class.


This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.