# Defining key equivalence in a hash

**URL:** <https://www.ruby-forum.com/t/defining-key-equivalence-in-a-hash/78931>\
**Category:** Ruby\
**Created:** [December 10, 2006, 8:33pm UTC](https://www.ruby-forum.com/t/defining-key-equivalence-in-a-hash/78931 "2006-12-10T20:33:08Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![snk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@snk](https://www.ruby-forum.com/u/snk)\
**Post date:** [December 10, 2006, 8:33pm UTC](https://www.ruby-forum.com/t/defining-key-equivalence-in-a-hash/78931/1 "2006-12-10T20:33:08Z")

</div>

Hello,

I’m trying to make two keys equivalent by having their #hash method  
produce the same result. But this does not seem to work:

irb(main):001:0\> class K; def hash; 90; end; end  
=\> nil  
irb(main):002:0\> h = {}  
=\> {}  
irb(main):003:0\> h[K.new] = 1  
=\> 1  
irb(main):004:0\> h.key? K.new # \<---- I want this to return true!  
=\> false

What am I missing?

Thanks for your consideration.

---

<div class="post-metadata">

**Author:** ![snk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@snk](https://www.ruby-forum.com/u/snk)\
**Post date:** [December 10, 2006, 8:41pm UTC](https://www.ruby-forum.com/t/defining-key-equivalence-in-a-hash/78931/2 "2006-12-10T20:41:48Z")

</div>

If you put K.new into a variable, and then check for that, it will  
return true:

irb(main):001:0\> class K; def hash; 90; end; end  
=\> nil  
irb(main):002:0\> h = {}  
=\> {}  
irb(main):003:0\> k = K.new  
=\> #\<K:0xb7cac4ac\>  
irb(main):004:0\> h[k] = 1  
=\> 1  
irb(main):005:0\> h[k]  
=\> 1  
irb(main):006:0\> h.key? k  
=\> true

It’s because K.new creates a new location in memory for each call to it,  
but h.key? checks the location in memory, not the contents of the keys  
and the objects passed to it. So if you call K.new twice, each will  
return a new location in memory.

Dan

---

<div class="post-metadata">

**Author:** ![snk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@snk](https://www.ruby-forum.com/u/snk)\
**Post date:** [December 10, 2006, 8:55pm UTC](https://www.ruby-forum.com/t/defining-key-equivalence-in-a-hash/78931/3 "2006-12-10T20:55:52Z")

</div>

On Mon, 11 Dec 2006, Suraj K. wrote:

> =\> 1  
> irb(main):004:0\> h.key? K.new # \<---- I want this to return true!  
> =\> false
> 
> What am I missing?

K#eql?

for example

harp:~ \> cat a.rb  
class K  
attr ‘key’  
def initialize() @key = 42 end  
def hash() @key.hash end  
def eql?(other) other.key == @key end  
end

p K.new =\> ‘which’, K.new =\> ‘one’

harp:~ \> ruby a.rb  
{#\<K:0xb75cca34 @key=42\>=\>“one”}

regards.

-a

---

<div class="post-metadata">

**Author:** ![snk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@snk](https://www.ruby-forum.com/u/snk)\
**Post date:** [December 10, 2006, 8:53pm UTC](https://www.ruby-forum.com/t/defining-key-equivalence-in-a-hash/78931/4 "2006-12-10T20:53:51Z")

</div>

On Dec 10, 2006, at 11:33 , Suraj K. wrote:

> =\> 1  
> irb(main):004:0\> h.key? K.new # \<---- I want this to return true!  
> =\> false
> 
> What am I missing?

class K; def eql?(other) true; end; end

#eql? is called if o1.hash == o2.hash. If #eql? returns true the  
objects belong to the same index.

–  
Eric H. - removed\_email\_address@domain.invalid - [http://blog.segment7.net](http://blog.segment7.net)

I LIT YOUR GEM ON FIRE!
