Ruby and Java equality usage

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

been on a Java subject, things would have been completely different
;-), but here I just try to keep myself “low profile” and extract as
information as possible.

You are doing a great job.

Still, I have formulated a conclusion in the previous post, and that

will be the one that will go to the entry for update:

#eql? is just syntactic sugar of #==, needed for objects used as keys
in hashes (because hash implementation doesn’t like to use #==, but
only #eql?). If your class needs to override #==, than just delegate
#eql? implementation to #==.

Please be aware that this is in contradiction to the official
documentation.
Maybe the doc is wrong but nobody has claimed that so far.
It will also break Hash lookup unless the reimplementation of #== is
very
careful!
( I will try to demonstrate this as soon as I have a little time )

Hopefully everybody is backing me up on this one even if they think that
is
how it should be. Right now it is not how it is.

Cheers
Robert

cheers and once again thanks,

… and still wondering how is this answering my question (however
will take a natural drift depending on the point of views of the
Now I would love to answer your question but maybe it would be easier if
Just my pov, hopefully cheered you up a bit.


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

Rober, thanks and thanks. I think you are right. I am a little sad
because I have hoped to find a good answer to this, so that others
will have a good reference for this subject and will not have to pass
through phylosophical times as I had when reading for the first time
about equality in Ruby.

Unfortunately, even if I play with Ruby for almost 2 years, I don’t
consider that I have enough knowledge to come up with authoritative
posts, so this is the reason for my mildy posts. If this would have
been on a Java subject, things would have been completely different
;-), but here I just try to keep myself “low profile” and extract as
information as possible.

Still, I have formulated a conclusion in the previous post, and that
will be the one that will go to the entry for update:

#eql? is just syntactic sugar of #==, needed for objects used as keys
in hashes (because hash implementation doesn’t like to use #==, but
only #eql?). If your class needs to override #==, than just delegate
#eql? implementation to #==.

cheers and once again thanks,

./alex

.w( the_mindstorm )p.

(http://themindstorms.blogspot.com)

On 6/27/06, Alex Y. [email protected] wrote:

been on a Java subject, things would have been completely different
Just to weigh in here on how I think of it, without this necessarily
uncharacteristic.


Alex

Thanks Alex. This part of explanation is quite good. Continuing on the
same direction I have tried to create a Hash where for Fixnum 2 and
Float 2 to be able to have different values. And I couldn’t figure out
any (except a somehow academic one: 2 => Fixnum, 2.0 => Float :slight_smile: ).

./alex

Alexandru P. wrote:

;-), but here I just try to keep myself “low profile” and extract as
information as possible.

Still, I have formulated a conclusion in the previous post, and that
will be the one that will go to the entry for update:

#eql? is just syntactic sugar of #==, needed for objects used as keys
in hashes (because hash implementation doesn’t like to use #==, but
only #eql?). If your class needs to override #==, than just delegate
#eql? implementation to #==.
Just to weigh in here on how I think of it, without this necessarily
being representative of any section of reality: #eql? is used for
value-and-type equality, where #== is used for value-equivalence. Thus
2.0 == 2 #=> true, 2.eql? 2.0 #=> false. For most types, they’ll be
identical, because 98 classes out of 100 simply don’t have a
value-equivalence relationship.

Of course, I could be very, very wrong about this, partially because the
only example I can think of off the top of my head where this is the
case is Fixnum == Float, and partially because it implies a certain
flexibility to the strongly-typed approach which seems quite
uncharacteristic.

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

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

Still, I have formulated a conclusion in the previous post, and that

will be the one that will go to the entry for update:

#eql? is just syntactic sugar of #==, needed for objects used as keys
in hashes (because hash implementation doesn’t like to use #==, but
only #eql?). If your class needs to override #==, than just delegate
#eql? implementation to #==.

Please be aware that this is in contradiction to the official documentation.

Can you please state how exactly this contradicts the official
documentation? I know you stated that before but somehow I miss your
answer to my question in an earlier post.

I don’t think there is a contradiction, delegating eql? to == is a
valid way to achieve that both are implemented the same - with the
added benefit that this is maintained for subclasses also as long as
they do not decide to override eql?.

Maybe the doc is wrong but nobody has claimed that so far.
It will also break Hash lookup unless the reimplementation of #== is very
careful!

What do you mean by “careful”? Of course, =='s implementation should
be reasonable but careful? What additional caveats do you see?

( I will try to demonstrate this as soon as I have a little time )

I’m looking forward to that.

Hopefully everybody is backing me up on this one even if they think that is
how it should be. Right now it is not how it is.

I’m not sure whether we read the same documentation - I get the
feeling that we interpret the same text in different ways.

Kind regards

robert

“Robert D.” [email protected] writes:

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.

Note something that’s peripherally related to == and eql? is the
method “hash”, which subclasses MUST override if they override eql? or
== so that the guarantee:

a.eql?(b) implies a.hash == b.hash

is maintained. If you don’t do this, your new objects will do all
sorts of weird things when you try to use them as keys in a Hash or
elements in a Set.

Hopefully I am not confused about the documentation I would hate to
create
such a fuss, let us see now:
The official ruby documentation is on http://www.ruby-doc.org/
with a link to the 1.8.4 core API here:
RDoc Documentation
which has in turn the documentation for class Object here:
class Object - RDoc Documentation and in particular the
documentation on
Object#== here :
class Object - RDoc Documentation
I am copying and pasting this documentation (again :wink: into this post:
[BEGIN COPY]
obj == other => true or false
obj.equal?(other) => true or false
obj.eql?(other) => true or false
http://www.ruby-doc.org/core/classes/Object.src/M001412.html

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

http://www.ruby-doc.org/core/classes/Object.src/M001414.html
[END COPY]

Apart from talking about the #equal? method it states clearly that
normally the #eql? stays a synonym for #== and we can conclude
that…

I cannot read!!! (in order to stay polite with myself).

ty very much

All my appologies to Alex and Robert and everyone else following this.
I guess I will change my signature to “Trust me I know what I am doing”
:frowning:

Robert

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

#eql? is just syntactic sugar of #==, needed for objects used as keys
in hashes (because hash implementation doesn’t like to use #==, but
only #eql?). If your class needs to override #==, than just delegate
#eql? implementation to #==.

While this a fairly good and useful statement, I would reword it just
a little bit to qualify that #eql? doesn’t have to be synonymous
with #==. It usually is, and unless you’re doing something far from
the norm it will be, but to call it “syntactic sugar” is not quite
accurate. I’d try a rewording like:

#eql? is used in hash key collision resolution. Under nearly all
circumstances, #eql? will be synonymous with #==, and if your class
needs to override #== it will be sufficient to alias #eql? to #==.
Just note there are rare exceptions.”

Jacob F.

On 6/27/06, Jacob F. [email protected] wrote:

#eql? is used in hash key collision resolution. Under nearly all
circumstances, #eql? will be synonymous with #==, and if your class
needs to override #== it will be sufficient to alias #eql? to #==.
Just note there are rare exceptions.

The one question I do have regarding this is why isn’t the default
implementation of Object#eql? as an alias to Object#==? The
documentation makes it clear that that’s the intended behavior, and
the common behavior for descendants of Object as well. It seems odd
that it’s not then codified as an alias. It seems redundant that we
have to always remember to alias #eql? if we override #==; why can’t
it be the default to already be an alias?

Jacob F.

On Wed, 28 Jun 2006, Jacob F. wrote:

that it’s not then codified as an alias. It seems redundant that we
have to always remember to alias #eql? if we override #==; why can’t
it be the default to already be an alias?

but alias take a copy of the aliased method - so you’d still need to
re-alias
right?

-a

“J” == Jacob F. [email protected] writes:

J> The one question I do have regarding this is why isn’t the default
J> implementation of Object#eql? as an alias to Object#==? The
J> documentation makes it clear that that’s the intended behavior, and
J> the common behavior for descendants of Object as well. It seems odd
J> that it’s not then codified as an alias. It seems redundant that we
J> have to always remember to alias #eql? if we override #==; why can’t
J> it be the default to already be an alias?

becuase this will change nothing

moulon% cat b.rb
#!/usr/bin/ruby
module Kernel
def x
puts “x”
end
alias xx x
end

class A
def x
puts “new x”
end
end

A.new.x
A.new.xx
moulon%

moulon% ./b.rb
new x
x
moulon%

Guy Decoux

On 6/27/06, ts [email protected] wrote:

becuase this will change nothing

Ah, good point. And after reading that, it got me thinking about how
the same question could be asked about why the default implementation
isn’t something like:

class Object
def eql?(other)
self == other
end
end

And thinking about that, I realized why. As Daniel M. mentioned,
the implication:

a.eql?(b) implies a.hash == b.hash

Should always be maintained. Now, if I recall correctly, the default
Object behavior is:

  • hash returns the object_id
  • equal? compares object_ids (this should never be overridden)
  • == is implemented in terms of equal?
  • eql? also compares object_ids (maybe also implemented in terms of
    eql?)

So by default, == and eql? are synonymous. But if we override ==, and
eql? were to implicitly follow, but we didn’t also override hash, the
above implication would no longer hold. Chaos ensues.

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…

Jacob F.