woshidan's loose leaf

ぼんやり勉強しています

自作クラスのテスト用にComparableモジュールと宇宙船演算子を使って同じオブジェクトか比較しやすくする

rubyでちょっとした処理を担当する自作クラスのテストをするとき、同じオブジェクトがどうかの比較する際、

assert_equal expect_obj.hash_value, actual_obj.hash_value # hash_valueはオブジェクトのidではないオブジェクトに特有の値

というような式をよく書いていました。ですが、そんなに広く使われないクラスであることがわかっているなら == 演算子の挙動をいじってしまって、

assert_equal expect_obj, actual_obj

とかけるようにしちゃっていいかも、ということでその方法をメモ。

class MyClass
  include Comparable # 宇宙船演算子の内容を元に `<=`, `>=` を使えるようにしてくれる

  def <=> other # 宇宙船演算子を使って、`<`, `==`, `>` 用の動作を定義
    return nil unless other.is_a? MyClass
    hash_value <=> other.hash_value # MyClassのオブジェクトが同一かどうか判断するための比較に、hash_valueの比較を使う
  end

  def hash_value
    # テストでも作りやすい値を元にハッシュ値を計算する
  end
end

参考

Effective Ruby

Effective Ruby