Ruby and Java equality usage

Hi!

I have posted a quick (reminder like) entry about how equality is
handled by Ruby and Java:

However, I feel I have missed to explain correctly why eql? and ==
are both needed (and I’ve been reading through Ruby books and searched
the ruby mailing list). Maybe somebody can clarify it and give a
better example. I will be happy to update the entry to reflect the
“new” knowledge.

./alex

On 6/26/06, Alexandru P. [email protected]
wrote:

are both needed (and I’ve been reading through Ruby books and searched
the ruby mailing list). Maybe somebody can clarify it and give a
better example. I will be happy to update the entry to reflect the
“new” knowledge.

I am surprised you did not find this reference, possibly I missed a
point in
your mail
http://www.ruby-doc.org/core/classes/Object.html#M001416
if I interpret it correctly

== is supposed to be redefined in classes in order to reflect identity
on an
“application” level.
equal? shall not be redefined in order to be available for object
identity,
something like
a.equal?(b) iff a.object_id == b.object_id
eql? is used for Hash entry comparison and is not redefined most of the
time

Just citing ruby doc for those who do not want to follow the link :wink:

Cheers
Robert

./alex


.w( the_mindstorm )p.

(http://themindstorms.blogspot.com)


Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.

  • Albert Einstein

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.

./alex

.w( the_mindstorm )p.

(http://themindstorms.blogspot.com)

On 6/26/06, Alexandru P. [email protected]
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.

Ok I knew I missed something.
Personally I find it quite useful to have “==” which I can adapt to my
needs, knowing that I can always count on “eql?” for object equality, I
might do things like this:

class MyString < String
def ==( otherString )
raise SomeException unless String === otherString
self.downcase.eql?( otherString.downcase )
end
end

x=MyString.new(“Alfa”)
x == “alfa” ==> true
x.eql?(“alfa”) ==> false

Now I think it is perfectly sane to say, no I think this is confusing I
will
keep my “==” and my “eql?” identical.
However be prepared that others will not :wink:

Cheers
Robert

Thanks for confirming my point :-). I couldn’t find a

Hey you will get me into trouble, I did not agree with your point, I
accept and understand it, my oppinion is not the only reasonable :wink:
seriously I think it is a feature, not the most important and maybe not
the
least dangerous but a feature nontheless.
Cheers
Robert

good/workable/meaningfull example for having different implementation

for == and eql?. I am still looking for.

./alex

.w( the_mindstorm )p.

(http://themindstorms.blogspot.com)


Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.

  • Albert Einstein

On 6/26/06, Robert D. [email protected] wrote:

Now I think it is perfectly sane to say, no I think this is confusing I will
keep my “==” and my “eql?” identical.
However be prepared that others will not :wink:

Cheers
Robert

Thanks for confirming my point :-). I couldn’t find a
good/workable/meaningfull example for having different implementation
for == and eql?. I am still looking for.

./alex

On 6/26/06, Robert D. [email protected] wrote:

Robert

Sorry for this… pls blame me :-). I assume it is a feature, but till
I can figure it out how to use it for me it is just not-yet-a-feature
(no intention to sound harsh).

./alex

.w( the_mindstorm )p.

(http://themindstorms.blogspot.com)

2006/6/26, Robert D. [email protected]:

On 6/26/06, Alexandru P. [email protected] wrote:

== is supposed to be redefined in classes in order to reflect identity on an
“application” level.
equal? shall not be redefined in order to be available for object identity,
something like
a.equal?(b) iff a.object_id == b.object_id
eql? is used for Hash entry comparison and is not redefined most of the time

I don’t fully agree to your point. Basically == and eql? are meant to
implement object equivalence. So if you implement == you should be
implementing eql? and hash, too. And usually == and eql? should
behave the same. The page you mention quotes “For objects of class
Object, eql? is synonymous with ==. Subclasses normally continue this
tradition, but there are exceptions.”. Numbers make a suble difference
here:

1 == 1.0
=> true
1.eql? 1.0
=> false

Personally I find this situation a bit odd. I’d prefer a single
equivalence relation per class not two.

Kind regards

robert

On Jun 26, 2006, at 13:09, Alexandru P. 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 S., 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.

On 6/26/06, Robert K. [email protected] wrote:

identity,
tradition, but there are exceptions.". Numbers make a suble difference
Kind regards

robert


Have a look: Robert K. | Flickr


Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.

  • Albert Einstein

On 6/26/06, Robert K. [email protected] wrote:

here:
Are you sure you read the page correctly?
I copy paste:

obj == other => true or false obj.equal?(other) => true or false obj.eql?(other) => true or false

Equalityâ??At the Object
http://www.ruby-doc.org/core/classes/Object.htmllevel,
== returns true only if obj and other are the same object.
Typically,
this method is overridden in descendent classes to provide
class-specific
meaning.

Unlike ==, the equal? method should never be overridden by subclasses:
it is
used to

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

determine object identity (that is, a.equal?(b) iff a is the same object
as
b).

The eql? method returns true if obj and anObject have the same
value.
Used by Hash http://www.ruby-doc.org/core/classes/Hash.html to test
members for equality. For objects of class
Objecthttp://www.ruby-doc.org/core/classes/Object.html,
eql? is synonymous with ==. Subclasses normally continue this tradition,
but
there are exceptions.
Numerichttp://www.ruby-doc.org/core/classes/Numeric.htmltypes, for

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

example, perform type conversion across ==, but not across eql?, so:

1 == 1.0 #=> true
1.eql? 1.0 #=> false

Now unless this is wrong, one can conclude that * #equal? shall not be redefined, * #eql? should not be redefined, unless 1's knowing what one's doing (not 4 me ;=) but * #== can be redefined freely.

1 == 1.0
=> true

1.eql? 1.0
=> false

Personally I find this situation a bit odd. I’d prefer a single

equivalence relation per class not two.

Although I do not feel the same that seems a normal concern, as I
pointed
out to the OP.
Honestly I think it depends on the programming culture we are coming
from
and when
in our mind these are synonyms we are likely to get bitten by that kind
of
code.
I can only offer you my sympathy not my agreement.

But if we discuss this long enough it will become completely engraved in
our
minds in we will be aware of it even if we do not like it :wink:

Cheers
Robert

Kind regards

On Jun 26, 2006, at 10:20 AM, Robert K. wrote:

and when
in our mind these are synonyms we are likely to get bitten by that
kind of
code.

At the moment I’m not so sure whether culture is the background. I
tend to think that there’s a more fundamental issue: having a single
equivalence relation defined on instances of a class seems to make
things easier in several areas and I believe that it rather reduces
programming errors.

Perhaps the issue is not so much having more than one, but having
unhelpful names for them. We don’t get confused by the variety of
each-like methods available. And no one forgets the difference
between times, upto, and downto, despite their similarities. If we
had ==, same_place_in_memory, same_in_hash, and same_object_id (or
whatever they are) people wouldn’t get confused even with lots of them.

– Elliot T.

2006/6/26, Robert D. [email protected]:

Are you sure you read the page correctly?

Pretty sure.

I copy paste:

Now unless this is wrong, one can conclude that

  • #equal? shall not be redefined,

Agreed.

  • #eql? should not be redefined, unless 1’s knowing what one’s doing (not 4
    me ;=)

Disagreed. If you redefine == then you should usually redefine eql?
as well and with similar semantics:

“[Method ==] Typically, this method is overridden in descendent
classes to provide class-specific meaning.”

“For objects of class Object, eql? is synonymous with ==. Subclasses
normally continue this tradition, but there are exceptions.”

So for subclasses == and eql? are usually synonymous even if == is
redefined.

but

  • #== can be redefined freely.

“Freely” is a bit too much freedom here for my taste. Of course we
can implement all these methods in any way we like to, but for a
typical class == and eql? should reflect equivalence of objects
(you’re probably mean the same, I’d just like to make the point in
order to help with the engraving :-)). And this in turn usually
depends on instance variables. So the behavior of Struct.new (which
defines a new class with a set of attributes) is pretty much the way
to go usually. There are other cases where only some attributes
should be used or even the default Object behavior retained but the
rule of thumb should be, if you implement ==, then also implement eql?
(for example by making it an alias) and hash and have all compare
based on member variables / attributes / observable state.

Personally I find this situation a bit odd. I’d prefer a single

equivalence relation per class not two.

Although I do not feel the same that seems a normal concern, as I pointed
out to the OP.
Honestly I think it depends on the programming culture we are coming from
and when
in our mind these are synonyms we are likely to get bitten by that kind of
code.

At the moment I’m not so sure whether culture is the background. I
tend to think that there’s a more fundamental issue: having a single
equivalence relation defined on instances of a class seems to make
things easier in several areas and I believe that it rather reduces
programming errors.

I can only offer you my sympathy not my agreement.

Although sympathy is better than nothing I’d rather convince you. :slight_smile:

But if we discuss this long enough it will become completely engraved in our
minds in we will be aware of it even if we do not like it :wink:

I’m the last one not to help engrave something like this in
everybody’s minds so I’ll happily continue this thread. :slight_smile:

Kind regards

robert

2006/6/26, Elliot T. [email protected]:

Perhaps the issue is not so much having more than one, but having
unhelpful names for them.

Yuck, basically one default equivalence relation is enough.

Kind regards

robert

Hmmm… for me it is not the name problem, but (hopefully nobody will
be agree because I keep repeating it) the fact that I really cannot
see a good example for having different implementations for == and
eql?. Once I see an example that makes sense, I will consider this
discussion closed (from my pov).

./alex

.w( the_mindstorm )p.

(http://themindstorms.blogspot.com)

On 6/27/06, Eric H. [email protected] wrote:

#eql? is used to resolve key collisions in hashes.

If two objects have the same #hash and are #eql? then they refer to
the same hash key. If two objects have the same #hash and are not
#eql? they refer to different hash keys.

… and still wondering how is this answering my question (however
thanks for the intention).

./alex

On Jun 26, 2006, at 4:38 AM, Alexandru P. wrote:

I have posted a quick (reminder like) entry about how equality is
handled by Ruby and Java:

http://themindstorms.blogspot.com/2006/06/parallel-of-equality-in-2-
worlds-ruby.html

However, I feel I have missed to explain correctly why eql? and ==
are both needed.

#eql? is used to resolve key collisions in hashes.

If two objects have the same #hash and are #eql? then they refer to
the same hash key. If two objects have the same #hash and are not
#eql? they refer to different hash keys.


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

On 6/27/06, Eric H. [email protected] wrote:

worlds-ruby.html
the same hash key. If two objects have the same #hash and are not
#eql? they refer to different hash keys.

… and still wondering how is this answering my question (however
thanks for the intention).

#eql? is needed because #== doesn’t do what #eql? does.

Or where you looking for a different answer?

Quoting myself:

The problem I was facing was to explain why == and eql? are both
needed, and when their implementation may be different.

The problem I see is not that #eql? is needed because #== doesn’t do
what #eql? does (because if you look logically at this sentence it
doesn’t make much sense: there is an infinitiy of methods xxx that
should be needed because #== doesn’t do what #xxx does :slight_smile: ).

I see no good reasons, and I haven’t found any good reference for
cases where these methods are differently implemented. At this moment
my interpretation is:

#eql? is just syntactic sugar of #==, needed for objects used in
hashes (because hashes use #eql? and not #==).

./alex

… and still wondering how is this answering my question (however
thanks for the intention).

Sorry for being blunt, you have started a thread, but that does not
mean
that the thread will stay focused on your initial question, many long
threads do not.
At the beginning of course 90% of the posters will try to do so, and so
did
I but than things
will take a natural drift depending on the point of views of the
posters.

I am sorry if you feel you did not get enough out of your question but
these
things happen :(.
On the other hand you have created a thread that has generated a
philosophical and civilized discussion, that is already a marvellous
thing
:).

Now I would love to answer your question but maybe it would be easier if
you
take a stronger position, like e.g. I think overriding == is harmfull
because or something like this.

I strongly feel that there is no answer, points of views shift slowly,
they do not jump, they depend so much on what you read or do.
A majority of people - of course I am not in, as usual :frowning: - agree with
your
pov, that also is something you should cheer about :wink:

Just my pov, hopefully cheered you up a bit.
Robert

./alex

On Jun 26, 2006, at 5:06 PM, Alexandru P. wrote:

However, I feel I have missed to explain correctly why eql? and ==
are both needed.

#eql? is used to resolve key collisions in hashes.

^^^ This line is the important one. I feel it describes adequately
what #eql? is needed for.

If two objects have the same #hash and are #eql? then they refer to
the same hash key. If two objects have the same #hash and are not
#eql? they refer to different hash keys.

… and still wondering how is this answering my question (however
thanks for the intention).

#eql? is needed because #== doesn’t do what #eql? does.

Or where you looking for a different answer?


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com