[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Hash#eql? and Hash key testing

Joel VanderWerf

12/4/2004 7:40:00 AM


The ri docs for Object#eql? say:

The +eql?+ method returns +true+ if _obj_ and _anObject_ have the
same value. Used by +Hash+ to test members for equality.

However, the second sentence doesn't seem to be consistent with the
behavior of Hash (and Set):

h1 = {1=>2, 3=>4}
h2 = {1=>2, 3=>4}

p h1.eql?(h2) # ==> true

h={h1=>true}

p h[h1] # ==> true
p h[h2] # ==> nil

Based on the docs, I would have expected

p h[h2] # ==> true

Have I misunderstood?


4 Answers

Michael C. Libby

12/4/2004 11:55:00 AM

0

On Sat, 2004-12-04 at 16:39 +0900, Joel VanderWerf wrote:
> The ri docs for Object#eql? say:
>
> The +eql?+ method returns +true+ if _obj_ and _anObject_ have the
> same value. Used by +Hash+ to test members for equality.
>
> However, the second sentence doesn't seem to be consistent with the
> behavior of Hash (and Set):
>
> h1 = {1=>2, 3=>4}
> h2 = {1=>2, 3=>4}
>
> p h1.eql?(h2) # ==> true
>
> h={h1=>true}
>
> p h[h1] # ==> true
> p h[h2] # ==> nil
>
> Based on the docs, I would have expected
>
> p h[h2] # ==> true
>
> Have I misunderstood?

h1 and h2 are not the same object above, though they are equivalent at
the time you test for equality. h1 could get new elements, as could h2.

mcl@saluki:~$ irb
irb(main):001:0> a = {1=>2,3=>4}
=> {1=>2, 3=>4}

irb(main):002:0> b = {1=>2,3=>4}
=> {1=>2, 3=>4}

irb(main):003:0> a == b
=> true

irb(main):004:0> a.__id__ == b.__id__
=> false

irb(main):005:0> c = {a=>true}
=> {{1=>2, 3=>4}=>true}

irb(main):006:0> c[b] = 'foo'
=> "foo"

irb(main):007:0> c
=> {{1=>2, 3=>4}=>"foo", {1=>2, 3=>4}=>true}

irb(main):008:0> a[5]=6
=> 6

irb(main):009:0> c
=> {{1=>2, 3=>4}=>"foo", {5=>6, 1=>2, 3=>4}=>true}

irb(main):010:0> a == b
=> false

With literals it's a different story:

irb(main):011:0> x = 5
=> 5

irb(main):012:0> y = 5
=> 5

irb(main):013:0> x == y
=> true

irb(main):015:0> c[x] = 'bar'
=> "bar"

irb(main):016:0> c
=> {5=>"bar", {1=>2, 3=>4}=>"foo", {5=>6, 1=>2, 3=>4}=>true}

irb(main):017:0> c[y]
=> "bar"

irb(main):018:0> x.__id__ == y.__id__
=> true

-Michael C. Libby, www.andsoforth.com



Christoph R.

12/4/2004 1:52:00 PM

0

Joel VanderWerf schrieb:

>
> The ri docs for Object#eql? say:
>
> The +eql?+ method returns +true+ if _obj_ and _anObject_ have the
> same value. Used by +Hash+ to test members for equality.
>
> However, the second sentence doesn't seem to be consistent with the
> behavior of Hash (and Set):
>
> h1 = {1=>2, 3=>4}
> h2 = {1=>2, 3=>4}
>
> p h1.eql?(h2) # ==> true
>
> h={h1=>true}
>
> p h[h1] # ==> true
> p h[h2] # ==> nil
>
> Based on the docs, I would have expected
>
> p h[h2] # ==> true
>
> Have I misunderstood?
>
No you have not, however hashes have different
Hash values (their ids - the same is true for Sets)
so all bets are off

----
class A
def ==(rhs)
true
end

alias :eql? :==
end

def test
a,b = A.new,A.new
ah = {a => true }
bh = {b => true }
p ah[b]
end

test # nil
class A
def hash
1
end
end

test # true

class A
remove_method :eql?
end


test # nil
---

/Christoph





Yukihiro Matsumoto

12/4/2004 1:56:00 PM

0

Hi,

In message "Re: Hash#eql? and Hash key testing"
on Sat, 4 Dec 2004 16:39:30 +0900, Joel VanderWerf <vjoel@PATH.Berkeley.EDU> writes:

|The ri docs for Object#eql? say:
|
| The +eql?+ method returns +true+ if _obj_ and _anObject_ have the
| same value. Used by +Hash+ to test members for equality.
|
|However, the second sentence doesn't seem to be consistent with the
|behavior of Hash (and Set):

You are right. "hash" should be redefined as well.

matz.


Christoph R.

12/4/2004 2:12:00 PM

0

Christoph schrieb:

> however hashes have different
> Hash values (their ids - the same is true for Sets)

Correction: If I remember correctly Set uses something

def hash
@rep_hash.hash
end

which is effectively the same as using the id of
the Sets as Hash values (which makes you wonder
why go through the trouble and provide the Set class
with a customized #hash method at all )

/Christoph