array operations

F

Ferenc Engard

Hi all!

What comparison (equality) the array operation '-' based on? I tried to
define ==, ===, even <=>, but none of them gets called. OTOH, if I have
two distinct string objects which happen to contain the same characters,
they are considered equal, even if the ids are not equal.

Thanks:
Ferenc

PS: Merry Christmas to all! :)
 
Y

Yukihiro Matsumoto

Hi,

In message "array operations"

|What comparison (equality) the array operation '-' based on? I tried to
|define ==, ===, even <=>, but none of them gets called. OTOH, if I have
|two distinct string objects which happen to contain the same characters,
|they are considered equal, even if the ids are not equal.

Close. It uses "eql?" internally, since comparison is done using
Hash.

matz.
 
F

Ferenc Engard

|What comparison (equality) the array operation '-' based on? I tried to
|define ==, ===, even <=>, but none of them gets called. OTOH, if I have
|two distinct string objects which happen to contain the same characters,
|they are considered equal, even if the ids are not equal.

Close. It uses "eql?" internally, since comparison is done using
Hash.

What does hash comparison mean? I have read the Object#hash and
Object#eql? documentation, but they do not mention arrays. Moreover,
there comes the question: what the default Object#hash do? It has a
generic algorithm which computes something based on the object's
attributes?

Anyway, I have to define both == and eql? in my classes to work
properly? What is the semantical difference of this two method? And then
I have to redefine hash also to ensure that a.eql?(b) implies
a.hash==b.hash?

I try to aim better next time,
Ferenc
 
F

Ferenc Engard

Samuel said:
Hash comparison means that it compares the value of Object#hash for each
object. This is where a quick look at the Ruby source is very enlightening.
Having had to do some battle with these methods recently myself, I have the
code fresh in my mind. Object#hash just returns the object ID by default.
This is done in C code, so if you override Object#object_id, it will not return
what you expect.

Sorry, I didn't look in the source, yet, but I have made some
experiments with this simple program:

class A
attr_accessor :x

def eql?(o) @x==o.x end

def hash
15
end
end

a=A.new
b=A.new
c=A.new
d=A.new

a.x=1
b.x=2
c.x=2
d.x=3

ar1=[a,b]
ar2=
ar3=[c]
ar4=[d]
ar5=[d,d]
ar6=[b,c]

puts "b.eql?(c)==true"
puts "[a,b]=="+(ar1).inspect
puts "[a,b].uniq=="+(ar1.uniq).inspect
puts "[a,b]-=="+(ar1-ar2).inspect
puts "[a,b]-[c]=="+(ar1-ar3).inspect
puts "[a,b]-[d]=="+(ar1-ar4).inspect
puts "[d,d].uniq=="+(ar5.uniq).inspect
puts "[b,c].uniq=="+(ar6.uniq).inspect
------------------------------------------------------------

The output is:

b.eql?(c)==true
[a,b]==[#<A:0x402d90ac @x=1>, #<A:0x402d8fe4 @x=2>]
[a,b].uniq==[#<A:0x402d90ac @x=1>, #<A:0x402d8fe4 @x=2>]
[a,b]-==[#<A:0x402d90ac @x=1>]
[a,b]-[c]==[#<A:0x402d90ac @x=1>]
[a,b]-[d]==[#<A:0x402d90ac @x=1>, #<A:0x402d8fe4 @x=2>]
[d,d].uniq==[#<A:0x402d8fbc @x=3>]
[b,c].uniq==[#<A:0x402d8fe4 @x=2>]

Which seems correct. Now if I comment out the hash method, the output
changes:

b.eql?(c)==true
[a,b]==[#<A:0x402d9174 @x=1>, #<A:0x402d90d4 @x=2>]
[a,b].uniq==[#<A:0x402d9174 @x=1>, #<A:0x402d90d4 @x=2>]
[a,b]-==[#<A:0x402d9174 @x=1>]
[a,b]-[c]==[#<A:0x402d9174 @x=1>, #<A:0x402d90d4 @x=2>]
[a,b]-[d]==[#<A:0x402d9174 @x=1>, #<A:0x402d90d4 @x=2>]
[d,d].uniq==[#<A:0x402d90ac @x=3>]
[b,c].uniq==[#<A:0x402d90d4 @x=2>, #<A:0x402d90c0 @x=2>]

I.e. b and c are no longer considered equal. Based on that, I have made
the following conclusion:

1. The array object first gets the hash of the objects it contains
2. If two object's hashes are not equal, then it considers as different
objects
3. If the hash values are equal, then if first.eql?(second) is true,
then it considers the objects as equal, otherwise not.

Just like a hash index in a database. So, if I am lazy, can I implement
the #hash method like this, and it will only result in a bigger
comparison executing time because of the more #eql? comparisons, but
will work correctly?

Thanks for the help:
Ferenc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top