# Hashes in Sets

**URL:** <https://www.ruby-forum.com/t/hashes-in-sets/131815>\
**Category:** Ruby\
**Created:** [March 13, 2008, 2:54pm UTC](https://www.ruby-forum.com/t/hashes-in-sets/131815 "2008-03-13T14:54:19Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![paul-au](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/f475e1/32.png) [@paul-au](https://www.ruby-forum.com/u/paul-au)\
**Post date:** [March 13, 2008, 2:54pm UTC](https://www.ruby-forum.com/t/hashes-in-sets/131815/1 "2008-03-13T14:54:19Z")

</div>

In Ruby 1.8.6-p111 (the latest version bundled with Mac OS X) and Ruby  
1.8.6-p114, the Set class will duplicate any Hash elements it contains:

> require ‘set’  
> s = Set.new  
> s \<\< {}  
> =\> #\<Set: {{}}\>  
> s \<\< {}  
> =\> #\<Set: {{}, {}}\>  
> s \<\< {:a =\> 1}  
> =\> #\<Set: {{:a=\>1}, {}, {}}\>  
> s \<\< {:a =\> 1}  
> =\> #\<Set: {{:a=\>1}, {}, {:a=\>1}, {}}\>

This seems to be due to the fact that the Set class uses a Hash  
internally to store its elements as keys and the Hash class itself  
does not equate two hashes with the same keys and values:

> {} == {}  
> =\> true  
> {}.eql?({})  
> =\> false  
> {}.hash == {}.hash  
> =\> false

Defining hash and eql? methods for Hash seems to correct this:

class Hash  
# Create a hash based on the keys and values.  
def hash  
“#{keys.join}#{values.join}”.hash  
end

```
 # To determine whether two hashes are the same, compare
 # their hashes.
 def eql?(other)
   hash == other.hash
 end

```

end

> {}.eql?({})  
> =\> true  
> {:a =\> 1}.eql?({:a =\> 1})  
> =\> true  
> {:b =\> 1, :a =\> 2}.eql?({:a =\> 2, :b =\> 1})  
> =\> true  
> s = Set.new  
> =\> #\<Set: {}\>  
> s \<\< {}  
> =\> #\<Set: {{}}\>  
> s \<\< {}  
> =\> #\<Set: {{}}\>

This issue of Hash’s eql? method has been brought up before in  
[http://groups.google.com/group/comp.lang.ruby/browse\_thread/thread/3ecd14d6e8bbc9cf/88d51de762c3dbd1](http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/3ecd14d6e8bbc9cf/88d51de762c3dbd1)  
and, more recently,  
[http://groups.google.com/group/comp.lang.ruby/browse\_thread/thread/572e8d8b01a7d24e/c5f532d868afab05](http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/572e8d8b01a7d24e/c5f532d868afab05)

I see that it has been fixed in Ruby 1.9.0 and was wondering if that  
change will also be implemented in the 1.8 series?

Thanks in advance,

– Paul
