# 自作クラスのオブジェクトをハッシュキーにするときの小技。 _published: 2010/04/12_ ![alt](http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/shunsuk/) 自作クラスのオブジェクトをハッシュキーにするときの小技。というタイトル記事を書いてみました。 自作クラスを定義します。 ```ruby class Person def initialize(name, age) @name = name @age = age end attr_accessor :name, :age end ``` このクラスのオブジェクトを2つ作ります。それをハッシュキーとして使います。 ```ruby aoi1 = Person.new("宮崎あおい", 24) aoi2 = Person.new("宮崎あおい", 24) hash = {} hash[aoi1] = 1 hash[aoi2] = 2 puts hash[aoi1] #=> 1 puts hash[aoi2] #=> 2 ``` そうすると、違うキーとして扱われます。インスタンス変数が同じなので、同じキーとして扱って欲しい。長い人生の中には、そんな時もあるでしょう。 ポイントは、 `Object#eql?` メソッドにあります。 ```ruby puts aoi1.eql? aoi2 #=> false puts aoi1.equal? aoi2 #=> false ``` `equal?` が `false` なのは、オブジェクトが違うので当たり前です。ですが、`eql?` も `false` になっています。それは、お前が悪いのです。 `eql?` を再定義しなければ、デフォルトで `equal?` と同じ挙動をするのです。つまり、お前が悪いのです。 `eql?` メソッドを再定義しましょう。 `eql?` メソッドを再定義する場合は、 `hash` メソッドも再定義する必要があります。 ```ruby class Person def initialize(name, age) @name = name @age = age end attr_accessor :name, :age def eql?(other) @name == other.name && @age == other.age end def hash [@name, @age].hash end end ``` 今度はどうでしょうか。 ```ruby aoi1 = Person.new("宮崎あおい", 24) aoi2 = Person.new("宮崎あおい", 24) puts aoi1.eql? aoi2 #=> true puts aoi1.equal? aoi2 #=> false ``` `eql?` が `true` になっていますね。 さあ、本番です。 ```ruby aoi1 = Person.new("宮崎あおい", 24) aoi2 = Person.new("宮崎あおい", 24) hash = {} hash[aoi1] = 1 hash[aoi2] = 2 puts hash[aoi1] #=> 2 puts hash[aoi2] #=> 2 ``` できましたよ。宮崎あおい(24)は、唯一無二の存在なのです。