The Comparable Module

· 3 min read · Updated March 7, 2026 · intermediate
comparable spaceship operators modules comparison

The Comparable module is one of Ruby’s most useful built-in modules. It lets you compare objects using familiar operators like <, >, and ==. In this guide, you’ll learn how to include Comparable in your classes and define the spaceship operator to enable powerful comparison functionality.

Why Use Comparable?

When you include the Comparable module in a class and define the <=> (spaceship) operator, Ruby automatically gives you all these methods for free:

  • < (less than)
  • <= (less than or equal)
  • > (greater than)
  • >= (greater than or equal)
  • == (equal)
  • between? (range check)

This is incredibly useful for sorting, finding minimum/maximum values, and any scenario where you need to compare objects.

Including Comparable in Your Class

Here’s a simple example using a Player class for a game:

class Player
  include Comparable

  attr_reader :name, :score

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

  def <=>(other)
    score <=> other.score
  end

  def to_s
    "#{name}: #{score}"
  end
end

The key is defining the <=> method, which returns:

  • -1 when self < other
  • 0 when self == other
  • 1 when self > other
  • nil when comparison isn’t possible

Using the Comparison Methods

Once Comparable is included, you get all the comparison operators:

player1 = Player.new("Alice", 1500)
player2 = Player.new("Bob", 2000)
player3 = Player.new("Charlie", 1500)

player1 < player2          # => true
player2 > player1          # => true
player1 <= player3         # => true (same score)
player1 == player3         # => true (same score)
player1 >= player2         # => false
player2.between?(player1, player3)  # => false

Practical Examples

Sorting Players

players = [
  Player.new("Alice", 1500),
  Player.new("Bob", 2000),
  Player.new("Charlie", 1800)
]

players.sort.each { |p| puts p }
# Output:
# Alice: 1500
# Charlie: 1800
# Bob: 2000

Finding Min/Max

players = [
  Player.new("Alice", 1500),
  Player.new("Bob", 2000),
  Player.new("Charlie", 1800)
]

players.min    # => #<Player:0x00007f8a2c3d4 @name="Alice", @score=1500>
players.max    # => #<Player:0x00007f8a2c3e5 @name="Bob", @score=2000>

Working with Numbers

Ruby’s core classes already include Comparable. Here are some examples:

# Strings are compared lexicographically
"apple" < "banana"    # => true
"zebra" > "apple"     # => true

# Numbers work as expected
5.between?(1, 10)    # => true
3.5.between?(3, 4)   # => false

# Arrays are compared element by element
[1, 2, 3] < [1, 2, 4]    # => true
[1, 2, 3] == [1, 2, 3]   # => true

Defining Multiple Comparison Criteria

You can chain comparisons for more complex sorting:

class Team
  include Comparable

  attr_reader :name, :wins, :losses

  def initialize(name, wins, losses)
    @name = name
    @wins = wins
    @losses = losses
  end

  def <=>(other)
    # First compare by wins, then by losses (fewer is better)
    result = other.wins <=> wins
    result.zero? ? losses <=> other.losses : result
  end
end

teams = [
  Team.new("Lions", 10, 4),
  Team.new("Tigers", 10, 3),
  Team.new("Bears", 8, 6)
]

teams.sort.each { |t| puts "#{t.name}: #{t.wins}-#{t.losses}" }
# Output:
# Tigers: 10-3
# Lions: 10-4
# Bears: 8-6

Common Mistakes

Forgetting to Include Comparable

# Without Comparable - won't work!
class BadExample
  def initialize(value)
    @value = value
  end

  def <=>(other)
    @value <=> other.value
  end
end

a = BadExample.new(5)
b = BadExample.new(10)
a < b  # => NoMethodError: undefined method `<'

Returning nil Incorrectly

Always return -1, 0, or 1 for valid comparisons:

def <=>(other)
  return nil if other.nil?  # Handle nil case explicitly
  @value <=> other.value
end

Summary

The Comparable module is a powerful way to add comparison functionality to your classes:

  1. Include Comparable in your class
  2. Define the <=> method returning -1, 0, or 1
  3. Get free comparison methods: <, <=>, >, >=, between?

This pattern is used throughout Ruby’s standard library. The String, Numeric, Array, and Hash classes all include Comparable. Now you can make your own classes work just as well with sorting, min/max operations, and comparison operators.