From: Alexandru Popescu Date: 2006-06-28T02:54:15+09:00 Subject: Re: Ruby and Java equality usage On 6/27/06, Jacob Fugal wrote: > On 6/27/06, Molitor, Stephen L wrote: > > > So the primary reason eql? is separate from == is that eql? needs to > > > be sure to follow hash. So now my question is: why isn't the default > > > implementation of eql? to compare hash instead of object_id? Then we > > > can override hash in cases where we want to, and not need to worry > > > about eql? unless we really need to... > > > > Hashes values don't have to be unique. Two distinct values may return > > the same hash code, but should return false for eql?. Remember how hash > > tables work from CS class -- if two hash codes are the same, the table > > chains the values together in a linked list under the same hash > > 'bucket'. To retrieve a value it first finds the relevant hash bucket > > via #hash, and then walks through the list sequentially using #eql? to > > compare. So #eql? had better return false for two distinct values. On > > the other hand, 'def hash; 1; end' is a perfectly correct albeit very > > inefficient #hash implementation. > > Ah, gotcha. Thanks for the refresher. :) Is it true then that > a.eql?(b) only if a.hash == b.hash? What's the damage in a.eql?(b) > returning true when in different buckets? As far as I can tell, #eql? > is only used internally by Hash -- it shouldn't be being called by > other code. So if a and b are in different buckets (different #hash > values), a.eql?(b) will never be called anyway. Relaxing that > restriction, can't we swing back the other way and ask again: > > Why doesn't the default implementation of Object#eql? just use #== internally? > > E.g.: > > class Object > def eql?(other) > self == other > end > end > > Jacob Fugal > I don't know if this is quite accurate. In Java world at least such an implementation is not enough good. Also, the known Hash implementations are using both hashCode() and equals() methods on key objects (and in this exact order). And I think it should be the same in Ruby (or pretty similar). ./alex -- .w( the_mindstorm )p. --- (http://themindstorms.blogspot.com)