Ruby Tips!

RubyのTipsを紹介します

ハッシュのキーになるクラスを定義する

あるクラスのオブジェクトがハッシュのキーになるためには、Object#hashObject#eql?が適切に再定義されていなければならない。ハッシュの内部において、Object#hashは値を格納するためのハッシュ値の計算に、Object#eql?はキーの同一性判定に使われる。

Object#eql?はオブジェクトが同一の場合に真を返し、オブジェクトが同一でない場合に偽を返すように再定義する。またObject#hashは整数を返し、かつObject#eql?が真を返す時は、同一の値を返すように再定義しなければならない。

以下は2つの数値を保持するクラスClazzを、ハッシュのキーになれるように実装した例である。ハッシュ値の計算には数値の排他的論理和を用いている。

class Clazz
  attr_accessor :a, :b

  def initialize(a, b)
    @a, @b = a, b
  end

  def hash
    @a ^ @b
  end

  def eql?(other)
    @a == other.a and @b == other.b
  end
end

hash = {}

hash[Clazz.new(1, 2)] = 'a'
hash[Clazz.new(2, 3)] = 'b'
hash[Clazz.new(3, 4)] = 'c'

p hash[Clazz.new(2, 1)] #=> nil
p hash[Clazz.new(1, 2)] #=> "a"
p hash[Clazz.new(2, 3)] #=> "b"
p hash[Clazz.new(3, 4)] #=> "c"