From: Robert Klemme Date: 2003-06-10T18:03:38+09:00 Subject: Re: array.uniq does not use == ? "Orion Hunter" schrieb im Newsbeitrag news:BAY2-F14247qXLFfJNw00027a03@hotmail.com... > I have a user defined object, Agent. And I want to pass my Agents around in > an Array. I've "mixed-in" the Comparable module, and defined <=> within > the class for sorting purposes. However, I _also_ want to be able to > perform Array.uniq/Array.uniq! as well, having the decision on the > "uniqueness" of the object derived from one particular attribute. > > My first thought was that all I need to do was define == in my Agent, and I > had hoped/assumed that this was the operator/function that Array.uniq looked > at when it executed. However, this is not the case. My next thought was > that Array.uniq might use <=>, and consider them "equal" if this returned 0, > however this was not the case either. > > I have tried defining the following for my object: > > <=> > == > === > eql? > equal? > > but none of them seem to be used in the Array.uniq comparison. Further > investigation showed that a combination of overriding eql?() and hash() will > do the trick (are these _both_ used in uniq?). Now, I know that I can > create my own class which inherits from Array, and override the uniq and > uniq! funciton to do what I want, but it seems like there is a less clumsly > solution (it just seems like I shouldn't have to override hash()). Any > suggestions? Thanks. Yes, you have to override method hash(). The only clean solution if you want to implement equivalence for a given class is to implement eql?, == and hash the way you need it. If you need ordering, too, you also have to implement <=>. Of course you can implement those in terms of each other minimizing the effort. See here for some remarks and examples: http://www.rubygarden.org/ruby?EquivalenceVsIdentity Cheers robert