[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Strange behavior of hash key

Traz

1/8/2005 6:52:00 AM

Hello all,
I want to use some hash who have a hash key. But, i don't understand
the hash key behaviour :

>> a={}
=> {}
>> a[{1,2}]='ok'
=> "ok"
>> a[{1,2}]
=> nil
>> a.keys
=> [{1=>2}]
>> a.keys[0] == {1,2}
=> true
>> a.keys[0].eql?({1,2})
=> false
>> a[a.keys[0]]
=> "ok"
So, why i can't access to the hash with a hash key ???

--
Traz

9 Answers

Matt Mower

1/8/2005 8:24:00 AM

0

Hi Traz,

On Sat, 8 Jan 2005 15:56:26 +0900, Traz <A.Reith@gmail.com> wrote:
> Hello all,
> I want to use some hash who have a hash key. But, i don't understand
> the hash key behaviour :
>
> >> a={}
> => {}
> >> a[{1,2}]='ok'
> => "ok"
> >> a[{1,2}]
> => nil

I believe the answer is because each time you use {1,2} you are
creating a new Hash object with the same contents but a different
object identity:

irb(main):017:0> {1,2}.object_id
=> 22400644
irb(main):018:0> {1,2}.object_id
=> 22396300

Because Hash uses Object#eql? to test for equality it makes them
different keys and hence your example fails.

Hope this helps,

Matt

--
Matt Mower :: http://matt...


Joel VanderWerf

1/8/2005 8:30:00 AM

0

Matt Mower wrote:
> Hi Traz,
>
> On Sat, 8 Jan 2005 15:56:26 +0900, Traz <A.Reith@gmail.com> wrote:
>
>>Hello all,
>>I want to use some hash who have a hash key. But, i don't understand
>>the hash key behaviour :
>>
>>
>>>>a={}
>>
>>=> {}
>>
>>>>a[{1,2}]='ok'
>>
>>=> "ok"
>>
>>>>a[{1,2}]
>>
>>=> nil
>
>
> I believe the answer is because each time you use {1,2} you are
> creating a new Hash object with the same contents but a different
> object identity:
>
> irb(main):017:0> {1,2}.object_id
> => 22400644
> irb(main):018:0> {1,2}.object_id
> => 22396300
>
> Because Hash uses Object#eql? to test for equality it makes them
> different keys and hence your example fails.
>
> Hope this helps,
>
> Matt
>

This behavior is changing in 1.9:

$ ruby -v -e 'a={ {1,2}=>3 }; p a[{1,2}]'
ruby 1.8.2 (2004-12-25) [i686-linux]
nil
$ ruby-snapshot -v -e 'a={ {1,2}=>3 }; p a[{1,2}]'
ruby 1.9.0 (2004-12-26) [i686-linux]
3


Traz

1/8/2005 8:47:00 AM

0

>Because Hash uses Object#eql? to test for equality it makes them
>different keys and hence your example fails.

Matt, string keys have the same behaviour, no ? :
>> "one".object_id
=> 22476232
>> "one".object_id
=> 22473868

>This behavior is changing in 1.9:
Thank Joel ! So finaly, it was a bug in 1.8 ?

--
Traz

Matt Mower

1/8/2005 10:01:00 AM

0

Hi Traz,

On Sat, 8 Jan 2005 17:51:25 +0900, Traz <A.Reith@gmail.com> wrote:
> >Because Hash uses Object#eql? to test for equality it makes them
> >different keys and hence your example fails.
>
> Matt, string keys have the same behaviour, no ? :
> >> "one".object_id
> => 22476232
> >> "one".object_id
> => 22473868
>

I think the answer here is that String redefines the eql? method to
compare content instead of 'object_id' so String literal keys will
work.

> >This behavior is changing in 1.9:
> Thank Joel ! So finaly, it was a bug in 1.8 ?
>

Did they define Hash#eql? in 1.9?

Regards,

Matt

--
Matt Mower :: http://matt...


Matt Mower

1/8/2005 10:17:00 AM

0

On Sat, 8 Jan 2005 10:00:58 +0000, Matt Mower <matt.mower@gmail.com> wrote:
> Hi Traz,
>
> On Sat, 8 Jan 2005 17:51:25 +0900, Traz <A.Reith@gmail.com > wrote:
> > >Because Hash uses Object#eql? to test for equality it makes them
> > >different keys and hence your example fails.
> >
> > Matt, string keys have the same behaviour, no ? :
> > >> "one".object_id
> > => 22476232
> > >> "one".object_id
> > => 22473868
> >
>
> I think the answer here is that String redefines the eql? method to
> compare content instead of 'object_id' so String literal keys will
> work.
>

Hmm... except that I tried a naive redefinition of Hash#eql? to:

def eql?( o ); self == o; end;

and the example still doesn't work. Guess I'm just wrong ;-)

M

--
Matt Mower :: http://matt...


timsuth

1/8/2005 10:36:00 AM

0

In article <d563731905010802175d37f678@mail.gmail.com>, Matt Mower wrote:
>On Sat, 8 Jan 2005 10:00:58 +0000, Matt Mower <matt.mower@gmail.com> wrote:
>> Hi Traz,
>>
>> On Sat, 8 Jan 2005 17:51:25 +0900, Traz <A.Reith@gmail.com > wrote:
>> > >Because Hash uses Object#eql? to test for equality it makes them
>> > >different keys and hence your example fails.
>> >
>> > Matt, string keys have the same behaviour, no ? :
>> > >> "one".object_id
>> > => 22476232
>> > >> "one".object_id
>> > => 22473868
>> >
>>
>> I think the answer here is that String redefines the eql? method to
>> compare content instead of 'object_id' so String literal keys will
>> work.
>>
>
>Hmm... except that I tried a naive redefinition of Hash#eql? to:
>
>def eql?( o ); self == o; end;
>
>and the example still doesn't work. Guess I'm just wrong ;-)

You also need to define Hash#hash so that eql objects have the same hash
code.

Robert Klemme

1/8/2005 1:29:00 PM

0


"Tim Sutherland" <timsuth@ihug.co.nz> schrieb im Newsbeitrag
news:slrnctvdsn.hpb.timsuth@europa.zone...
> In article <d563731905010802175d37f678@mail.gmail.com>, Matt Mower wrote:
>>On Sat, 8 Jan 2005 10:00:58 +0000, Matt Mower <matt.mower@gmail.com>
>>wrote:
>>> Hi Traz,
>>>
>>> On Sat, 8 Jan 2005 17:51:25 +0900, Traz <A.Reith@gmail.com > wrote:
>>> > >Because Hash uses Object#eql? to test for equality it makes them
>>> > >different keys and hence your example fails.
>>> >
>>> > Matt, string keys have the same behaviour, no ? :
>>> > >> "one".object_id
>>> > => 22476232
>>> > >> "one".object_id
>>> > => 22473868
>>> >
>>>
>>> I think the answer here is that String redefines the eql? method to
>>> compare content instead of 'object_id' so String literal keys will
>>> work.
>>>
>>
>>Hmm... except that I tried a naive redefinition of Hash#eql? to:
>>
>>def eql?( o ); self == o; end;
>>
>>and the example still doesn't work. Guess I'm just wrong ;-)
>
> You also need to define Hash#hash so that eql objects have the same hash
> code.

Note also that equivalence of Hashes is not a simple concept: in some
situations you want to include the default value and / or block into
equivalence and sometimes you don't. I guess that's the reason why this was
left open for quite some time. The most pragmatic solution is to define
hashes with the same key value pairs, the same default value and without a
block to be equivalent and all others to not be equivalent.

Kind regards

robert

Matt Mower

1/8/2005 2:46:00 PM

0

Hi Tim,

On Sat, 8 Jan 2005 19:36:26 +0900, Tim Sutherland <timsuth@ihug.co.nz> wrote:
> >Hmm... except that I tried a naive redefinition of Hash#eql? to:
> >
> >def eql?( o ); self == o; end;
> >
> >and the example still doesn't work. Guess I'm just wrong ;-)
>
> You also need to define Hash#hash so that eql objects have the same hash
> code.
>

Of course, I got sidetracked by eql? and forgot that the problem was,
ultimately, about the hashing function. The real answer was in the
difference between Object#hash which presumably uses object_id and
String#hash which uses length & content.

Thanks for putting me straight,

Matt

--
Matt Mower :: http://matt...


Charles Mills

1/8/2005 3:44:00 PM

0

This thread might be of interest:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...
-Charlie