[ruby]RakeのEarlyTimeクラス

Rakeのソースコードを読んでいたら、ValueObjectパターンの実装例として、非常に面白い例を見つけたので紹介しておきます。
実現している内容は、もっとも古い時間を表すクラスです。よくSQLなどで-999.99を最小値と定義したりしますが、そのRuby版と思ってもらうとわかりやすいですね。
EarlyTimeクラスは、

  • Singleton
  • 他の比較したら常に小さいと定義
  • 表示するとと表示する

だけのクラスです。

module Rake
  ....省略...

  # EarlyTime is a fake timestamp that occurs _before_ any other time value.
  class EarlyTime
    include Comparable
    include Singleton

    def <=>(other)
      -1
    end

    def to_s
      "<EARLY TIME>"
    end
  end

  EARLY = EarlyTime.instance
end

このEARYインスタンスがソートしたときに、もっとも古いオブジェクトにするためにTimeクラスの比較演算子<=>を新しい定義で書き換えています。

そして、もとからあるTimeクラスの比較演算子

  • EaryTimeと比較する時には、EarlyTimeの比較演算子を使用
  • EaryTime以外と比較するときには、Rubyの比較演算子を使用

するように書き換えています。

class Time
  alias rake_original_time_compare :<=>
  def <=>(other)
    if Rake::EarlyTime === other
      - other.<=>(self)
    else
      rake_original_time_compare(other)
    end
  end     
end

これで、時間でソートすると常に一番小さい値として、EarlyTimeクラスのオブジェクトが設定されるというわけ。
Rubyは面白いね。