Ruby's "spaceship" operator (<=>), AKA the three-way comparison operator, lets you compare two values. If the value on the left-hand side is less than the value on the right-hand side, it will return -1; if the value is greater, it will return 1; and if the values are the same, it will return 0:
1 <=> 2 # => -1 2 <=> 1 # => 1 1 <=> 1 # => 0
When you combine this concept with the Comparable mixin, you can unlock some nice behavior in your own classes.
Let's jump right into an example:
class Student
include Comparable
attr_reader :first_name, :last_name, :grade
def initialize(first_name, last_name, grade)
@first_name = first_name
@last_name = last_name
@grade = grade
end
def <=>(other_student)
grade <=> other_student.grade
end
endImplementing the spaceship operator allows us to do this:
s1 = Student.new("John", "Smith", 89)
s2 = Student.new("Jane", "Smith", 92)
s1 <=> s2 # => -1However, since we included the Comparable module and implemented the spaceship operator, we automatically gain access to the following:
<, <=, >, >=, ==, between?, clamp
And if you put these in a container that implements Enumerable, you also unlock things like:
sort, min, max, minmax, etc.
Let's play around with some of this:
s1 = Student.new("John", "Smith", 89)
s2 = Student.new("Jane", "Smith", 92)
s3 = Student.new("Bob", "Liu", 93)
s4 = Student.new("Ana", "Lee", 74)
students = [s1, s2, s3, s4]
students.sort
# => [
#<Student:0x00000001531aaa28 @first_name="Ana", @last_name="Lee", @grade=74>,
#<Student:0x00000001531aac30 @first_name="John", @last_name="Smith", @grade=89>,
#<Student:0x00000001531aab68 @first_name="Jane", @last_name="Smith", @grade=92>,
#<Student:0x00000001531aaac8 @first_name="Bob", @last_name="Liu", @grade=93>
]
s1.between?(s4, s3) # 89 is between 74 and 93
# => true
s1 > s2 # 89 is smaller than 92
# => false
students.minmax # returns the min and the max
# => [
#<Student:0x00000001531aaa28 @first_name="Ana", @last_name="Lee", @grade=74>,
#<Student:0x00000001531aaac8 @first_name="Bob", @last_name="Liu", @grade=93>
]In summary, by implementing the <=> operator and incorporating the Comparable mixin, you gain access to a variety of useful features!