2012-06-28 2 views
5

私はハッシュのキーとして使用したいオブジェクトの周りにラッパークラスを持っています。 wrappedオブジェクトとunwrapperオブジェクトは、同じキーにマップする必要があります。鍵を比較するときにRubyのハッシュを使用する平等テストはありますか?

簡単な例は、このようになります。

class A 
    attr_reader :x 
    def initialize(inner) 
    @inner=inner 
    end 
    def x; @inner.x; end 
    def ==(other) 
    @inner.x==other.x 
    end 
end 
a = A.new(o) #o is just any object that allows o.x 
b = A.new(o) 
h = {a=>5} 
p h[a] #5 
p h[b] #nil, should be 5 
p h[o] #nil, should be 5 

私はEQ、==、===試してみましたか?すべて無駄にハッシュします。

+1

あなたは、@のinner' 'にほとんどのメソッドを委譲したい場合は、' SimpleDelegator'に見たいと思うかもしれません。 –

+0

Thanks @ Marc-AndréLafortune!今日何か新しいことを学んだ – alexloh

答えて

4

ハッシュはkey.eqlを使用しますか?キーが等しいかどうかをテストします。独自のクラスのインスタンスをハッシュのキーとして で使用する必要がある場合は、 の両方を定義することをお勧めします。ハッシュ法などがあります。ハッシュメソッドは、a.eql?(b)がa.hash == b.hashを意味するプロパティを持っている必要があります。

そう...

class A 
    attr_reader :x 
    def initialize(inner) 
    @inner=inner 
    end 
    def x; @inner.x; end 
    def ==(other) 
    @inner.x==other.x 
    end 

    def eql?(other) 
    self == other 
    end 

    def hash 
    x.hash 
    end 
end 
+0

ああ、それでは両方を使用します。今私はそれについて考えて、実際のテストのためにバケツを取得するために 'hash'を使用し、' eql? 'を使用することは理にかなっています。私はそれもJavaで同じだと思う – alexloh

+0

しかし、なぜ 'eq?'のデフォルトの実装は '=='を使わないのですか? – ony

4

eql?hashを定義する必要があります。

Hashのドキュメントはありませんでしたが、has been improved recentlyです。