"ts" <decoux@moulon.inra.fr> schrieb im Newsbeitrag
news:200501271111.j0RBBJu07211@moulon.inra.fr...
> I don't see eql? called here - maybe it's an internal optimization
that
> short circuits identity. Or did I miss something?
If 2 object have different hash value, it don't need to call eql?
Ah, yes of course. That's it! Thanks for reminding me.
Now if they have the same hash value :
* if eql? return true, this is the "same" object (i.e. it will use the
same key)
* otherwise there is collision
Of all what you said I don't understand your last point: Why is there a
collision?
class Foo; def hash() 0 end end
=> nil
h = {Foo.new => 1, Foo.new => 2}
=> {#<Foo:0x101a9808>=>2, #<Foo:0x101a9898>=>1}
h.keys.uniq
=> [#<Foo:0x101a9808>, #<Foo:0x101a9898>]
And indeed a redefined Dummy clarifies this:
class Dummy
def eql?(x) puts "eql?"; super end
def equal?(x) puts "equal?"; super end
def ==(x) puts "=="; super end
def hash() puts "hash"; 0 end
def id() puts "id"; super end
end
h={Dummy.new => 1, Dummy.new => 2}
hash
hash
eql?
=> {#<Dummy:0x1018da28>=>2, #<Dummy:0x1018da88>=>1}
h.keys.uniq
hash
hash
eql?
=> [#<Dummy:0x1018da28>, #<Dummy:0x1018da88>]
Again a reminder that it's always a good idea to override #hash, #== and
#eql? in one go for classes that should be used as hash keys or in sets.
Object#hash return the id of object
Yeah, but that might be overridden in an arbitrary way. Normally one
can't rely on that #hash tells anything about the identity of an instance
other than probably that instances with different hash are not identical
and not equivalent.
Kind regards
robert