[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

What does it take to make an object hashable, no really...

Just Another Victim of the Ambient Morality

9/13/2006 2:50:00 PM

Suppose I want to define a class and be able to use this class as a key
to a hash. How does one do this? ...And please test your response before
posting it.
Secondly, if an objects works in a hash, is it guaranteed to work in a
set?
Thank you...



6 Answers

Farrel Lifson

9/13/2006 3:11:00 PM

0

On 13/09/06, Just Another Victim of the Ambient Morality
<ihatespam@rogers.com> wrote:
> Suppose I want to define a class and be able to use this class as a key
> to a hash. How does one do this? ...And please test your response before
> posting it.
> Secondly, if an objects works in a hash, is it guaranteed to work in a
> set?
> Thank you...
>
>
>
>
>

As far as I know all objects respond to .hash and can therefore be
used as keys.
irb(main):001:0> class HashableClass
irb(main):002:1> end
=> nil
irb(main):003:0> h1 = HashableClass.new
=> #<HashableClass:0x2dc4270>
irb(main):004:0> h2 = HashableClass.new
=> #<HashableClass:0x2dc1c78>
irb(main):005:0> h1.hash
=> 23994680
irb(main):006:0> h2.hash
=> 23989820
irb(main):007:0> hash = {h1=>"H1",h2=>"H2"}
=> {#<HashableClass:0x2dc4270>=>"H1", #<HashableClass:0x2dc1c78>=>"H2"}
irb(main):008:0> hash[h1]
=> "H1"

If you undefine hash or have it return nil, then you can run into problems:
irb(main):009:0> def h1.hash
irb(main):010:1> nil
irb(main):011:1> end
=> nil
irb(main):012:0> hash[h1]
NoMethodError: undefined method `%' for nil:NilClass
from (irb):12:in `[]'
from (irb):12
irb(main):013:0>

Farrel

Tim Pease

9/13/2006 3:26:00 PM

0

On 9/13/06, Just Another Victim of the Ambient Morality
<ihatespam@rogers.com> wrote:
> Suppose I want to define a class and be able to use this class as a key
> to a hash. How does one do this? ...And please test your response before
> posting it.

Chapter 22 of the Programming Ruby, The Pragmatic Programmer's Guide

A key must respond to "hash" and the value returned must not change.

What is not in the book is that you must also provide an eql? method
that evaluates to true when two objects are equivalent.

class C
def hash() "C".hash end
end

h = {}
h[C.new] = 1
h[C.new]

=> nil

class C
def eql?(other) true end
end

h[C.new]

=> 1



> Secondly, if an objects works in a hash, is it guaranteed to work in a
> set?

No idea about this one. Have not used the Ruby Set class thus far.

TwP

William Grosso

9/13/2006 3:28:00 PM

0

Tim Pease wrote:
> On 9/13/06, Just Another Victim of the Ambient Morality
> <ihatespam@rogers.com> wrote:
>> Suppose I want to define a class and be able to use this class as
>> a key
>> to a hash. How does one do this? ...And please test your response
>> before
>> posting it.
>
> Chapter 22 of the Programming Ruby, The Pragmatic Programmer's Guide
>
> A key must respond to "hash" and the value returned must not change.
>
> What is not in the book is that you must also provide an eql? method
> that evaluates to true when two objects are equivalent.
>

More precisely: if two objects are equivalent, they should have the same
hash value, and eql? should return true.


Bill



Just Another Victim of the Ambient Morality

9/13/2006 3:43:00 PM

0


"Tim Pease" <tim.pease@gmail.com> wrote in message
news:69f66b790609130825u2a1df39bgff8899f3b881a1a1@mail.gmail.com...
> On 9/13/06, Just Another Victim of the Ambient Morality
> <ihatespam@rogers.com> wrote:
>> Suppose I want to define a class and be able to use this class as a
>> key
>> to a hash. How does one do this? ...And please test your response
>> before
>> posting it.
>
> Chapter 22 of the Programming Ruby, The Pragmatic Programmer's Guide
>
> A key must respond to "hash" and the value returned must not change.
>
> What is not in the book is that you must also provide an eql? method
> that evaluates to true when two objects are equivalent.

Yes! I found that suspiciously missing from the book, as well. After
a bit of thought, you figure out that some equality method must be
implemented as well as the hash method but I didn't know if it were ==,
eql?, <=>, or whatever...
Thanks a lot!


>> Secondly, if an objects works in a hash, is it guaranteed to work in
>> a
>> set?
>
> No idea about this one. Have not used the Ruby Set class thus far.

That's too bad. One would hope it will have exactly the same
requirements as for hash but who knows?



Farrel Lifson

9/13/2006 3:52:00 PM

0

On 13/09/06, Tim Pease <tim.pease@gmail.com> wrote:
> On 9/13/06, Just Another Victim of the Ambient Morality
> <ihatespam@rogers.com> wrote:
> > Suppose I want to define a class and be able to use this class as a key
> > to a hash. How does one do this? ...And please test your response before
> > posting it.
>
> Chapter 22 of the Programming Ruby, The Pragmatic Programmer's Guide
>
> A key must respond to "hash" and the value returned must not change.
>
> What is not in the book is that you must also provide an eql? method
> that evaluates to true when two objects are equivalent.
>
> class C
> def hash() "C".hash end
> end
>
> h = {}
> h[C.new] = 1
> h[C.new]
>
> => nil
>
> class C
> def eql?(other) true end
> end
>
> h[C.new]
>
> => 1
>
>
>
> > Secondly, if an objects works in a hash, is it guaranteed to work in a
> > set?
>
> No idea about this one. Have not used the Ruby Set class thus far.
>
> TwP
>
>

Is there a reason why an implementation of eql? is needed instead of
just being able to define <=>?

Farrel

Tim Pease

9/13/2006 4:27:00 PM

0

On 9/13/06, Farrel Lifson <farrel.lifson@gmail.com> wrote:
>
> Is there a reason why an implementation of eql? is needed instead of
> just being able to define <=>?
>
> Farrel

The results of <=> are always a Fixnum -- specifically 1, 0, -1

A Fixnum always evaluates to true in a boolean expression in Ruby.
You have to use eql? if you want to get a true/false result.

TwP