2016-03-05 39 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