[Ruby] eql? and hash on Sets

Ryan Davis ryand-ruby at zenspider.com
Sat Nov 24 18:09:10 PST 2007


On Nov 24, 2007, at 10:35 , Aaron Patterson wrote:

> Given the behavior of Array#hash and Array#eql?, what would you expect
> Set#hash and Set#eql? to do?  I expected Set to behave the same way as
> Array, but it does not.

I would expect set to behave more like Hash than Array... or at least,  
I would expect it to act like some genetic freak merge of the two.

> However, I was surprised to find that Set
> implements eql? and hash.  That leads me to believe that the original
> intent was for Set to behave like Array in that department, and that
> this is a bug.

Why would the implementation of #eql? and #hash lead you to believe  
that it'd act like an Array? I don't see how that follows.

That said, it seems wrong that Set#eql? is defined by Hash#eql? (which  
defaults to Object#eql? and is therefor the same as Object#equal?-- 
object identity). So yes, it seems like a bug, sorta.

> As far as I can tell, no two Sets can eql? each other.

No two different sets...

> % irb
> >> require 'set'
> => true
> >> s = Set.new [1, 2, 3]
> => #<Set: {1, 2, 3}>
> >> s2 = s
> => #<Set: {1, 2, 3}>
> >> s.eql? s2
> => true

The real question is, how exactly are you abusing sets that makes you  
poke into this area? Using them as hash keys?

> >> h = {}
> => {}
> >> h[s] = 42
> => 42
> >> h
> => {#<Set: {1, 2, 3}>=>42}
> >> s2 = Set.new [1, 2, 3]
> => #<Set: {1, 2, 3}>
> >> h[s2]
> => nil

that seems wrong.

as does this:

> >> s.hash
> => 21280
> >> s2.hash
> => 147860

both of those are more dependent on Hash itself than on Set.



More information about the Ruby mailing list