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.