On 9/1/06, Jia Pu <very.funny.j / gmail.com> wrote: > Thanks, that works. > I am wondering the requirement of #eql? is necessary. If the programmer > wants to have non-equal objects to have same hash value, it is totally up to > the programmer. $ri Object#hash ------------------------------------------------------------ Object#hash obj.hash => fixnum ------------------------------------------------------------------------ Generates a +Fixnum+ hash value for this object. This function must have the property that +a.eql?(b)+ implies +a.hash == b.hash+. The hash value is used by class +Hash+. Any hash value that exceeds the capacity of a +Fixnum+ will be truncated before being used. Note that the requirement is that if a.eql?(b) then a.hash must be == b.hash This is because hash is used as a test to avoid a potentially expensive .eql? test, if two object's DON'T have the same hash value they are assumed to be not equal. A Hash (I'm assuming here based on how hash algorithms work in general) uses the hash of the key to compute an initial slot to store a reference to an object when you put the object, at a particular key in the hash with []=. If that slot is empty that's where it goes. If it's not, meaning that there's a key there with the same hash, then it uses eql? to see if it's the right slot, and if not it's called a hash collision, and the hash calculates a new slot and repeats the process. Finding the object with a given key works basically the same way. So the net of all this is, if you want hash to treat two different instances of your class as the same then you must redefine eql?, and whenever you redefine .eql? then you need to redefine hash to make sure that the implication in the specification of Object#hash holds. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/