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
— if the current object is "less than" the other object;0
— if both objects are "equal";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.