Spaceship operator

While developing applications I strive to make my code more concise and expressive. Using comparison operators helps make my code clearer and more declarative.

Let’s say that we have an application that tracks personal expenses. We would like to be able to compare our expenses using simple comparison operators like > and <. To do this we will use the Ruby module Comparable which makes it easy to compare objects by mixing in the module into our class. The key method involved is the comparison method <=> or the spaceship operator, as it is usually called. Within this method we define what we mean by less than, equal to, and greater than. Here is what our Expense class looks like:

class Expense
  include Comparable
  attr_accessor :amount
  def <=>(expense)
    if self.amount < expense.amount
      -1
    elsif self.amount > expense.amount
      1
    else
      0
    end
  end
end

Our spaceship operator must return -1 for less than, 1 for greater than, and 0 for equal to, these are the predefined return values that are signals to Ruby. The method above works fine, but we can do better. Since we will be storing expenses as floating-point numbers, we can piggyback on the existing <=> method of the Float class. We can make rewrite this method even more concise:

def <=>(expense)
  self.amount <=> expense.amount
end

Within our application we now have a more expressive way to compare our expenses:

..
if @current_expense > @previous_expense
  expense_alert :exceeding_expense

Leave a comment