On Jun 26, 2006, at 13:09, Alexandru Popescu wrote:

> Thanks Robert. I have used that information and I am even linking to
> it. The problem I was facing was to explain why == and eql? are both
> needed, and when their implementation may be different.

I'll give you an actual use-case from my current work in natural  
language processing.  I have Word objects which have various  
properties, not all of which are important to 'equality' for Words  
(and which may vary for two equal words).  As an example, a verb  
might have two different subjects in two different contexts - from a  
Word-oriented perspective, they're identical, from other perspectives  
they may not be.

I define '==' to reflect what equality should be for words, something  
like this:

class Word
   attr :stem, :text, :category, :pos, :etc
   def ==(word)
     # a 'stem' is the root form of a word,
     # e.g., 'looking'.stem => 'look'
     self.stem == word.stem
   end
end

On the other hand, when I'm comparing words, I want to make sure I'm  
not generating spurious matches by comparing a particular Word to  
itself, so I check for that with the default implementation of eql?   
The only way to avoid using eql? would be to invent something  
functionally equivalent - maybe a variable to hold the precise  
position of the word in the text, and then a predicate method to  
compare positions.  But eql? is there, so that's what I use.

Coming from C, I tend to think of Ruby variables as pointers to  
values, so I tend to think of the difference between eql? and == as  
akin to the following:

Ruby eql? - i.e., are they at the same spot in memory?
   int* a; int* b;
   a == b;

Ruby ==  - i.e., do they contain the same value?
   int* a; int* b;
   *a == *b;

So, in a general case, I'd say that you'd implement == and eql?  
differently when you can have multiple objects where identity is  
defined on a subset of their attributes (including their object id).   
For post authors on a mailing list, to make up a simple example:

class Author
   attr :email, :name
   def ==(other)
     # one email may have many names:
     # Matthew Smillie, matt, Matthew B Smillie, ...)
     self.email == other.email
   end
end

matthew smillie

[1] - a stem is the root form of a word, e.g., 'looking' -> 'look',  
'bridges' -> 'bridge' and so forth.  Google on 'Porter Stemmer' for a  
vast amount of background and a popular implementation.