"<=>"メソッドのオーバーライドによる比較の実装

名著"Effective Ruby"に「"<=>"とComparableモジュールで比較を実装しよう」と書いてあったので江戸時代の身分制度を実装してみた。

class Rank
  include Comparable
  attr_reader :name
  NAMES = ['士', '農', '工', '商'].map(&:freeze).freeze

  def initialize(name)
    unless NAMES.include?(name)
      raise(ArgumentError, "Argument must be any of #{NAMES}")
    end
    @name = name
  end

  def <=> (other)
    NAMES.index(self.name) <=> NAMES.index(other.name)
  end
end
['農', '工', '士', '商'].map{|s| Rank.new(s)}.sort.map{|rank| rank.name} 
# => ["士", "農", "工", "商"]

Rank.new('農')  < Rank.new('商')  # => true
Rank.new('農')  > Rank.new('商')  # => false
Rank.new('士') == Rank.new('士')  # => true
Rank.new('工').between?(Rank.new('士'), Rank.new('商'))  # => true

おしまい。