2016-03-05 37 views
0

Hash檢查它的鍵:eql?覆蓋不哈希與<code>eql?</code>工作

foo = 'str' 
bar = 'str' 

foo.equal?(bar) #=> false 
foo.eql?(bar)  #=> true 

h = { foo => 1 } 
h[foo]   #=> 1 
h[bar]   #=> 1 

但是,如果我用我自己的類作爲重點,這並不工作:

class Cl 
    attr_reader :a 
    def initialize(a) 
     @a = a 
    end 
    def eql?(obj) 
     @a == obj.a 
    end 
end 

foo = Cl.new(10) 
bar = Cl.new(10) 

foo.equal?(bar) #=> false 
foo.eql?(bar)  #=> true 

h = { foo => 1 } 
h[foo]   #=> 1 
h[bar]   #=> nil 

爲什麼最後線返回nil而不是1

+0

'puts'總是返回'nil'。 –

+0

@ sagarpandya82我認爲你不明白這一點。 – sawa

+2

@BиталийПапроцький如果你小心地說出了這個問題本身就很好。如果您閱讀這裏的評論並正確地設置您的問題,downvote可能變成upvote。 – sawa

回答

1

eql?必須配合使用一個hash方法返回的哈希碼:

class Cl 
    attr_reader :a 
    def initialize(a) 
    @a = a 
    end 
    def eql?(obj) 
    @a == obj.a 
    end 
    def hash 
    @a 
    end 
end 

參見this blog post

+1

[documentation](http://ruby-doc.org/core-2.3.0/Hash.html#class-Hash-label-Hash+Keys)的附帶部分:*「兩個對象表示相同的散列如果'hash'和'eql''方法被覆蓋以提供有意義的用戶定義的類可以被用作散列鍵,那麼它們的'hash'值是相同的,並且這兩個對象是'eql?'行爲。「* – Stefan

+2

順便說一句,'散列'應該返回一個'Fixnum' – Stefan