Imagine a class including comparable like this:

```
class Element
include Comparable
attr_accessor :name, :pos_x, :pos_y
def initialize(name, pos_x, pos_y)
@name = name
@pos_x = pos_x
@pos_y = pos_y
end
def <=>(other)
if (@pos_x == other.pos_x) and (@pos_y == other.pos_y)
return 0
else
return @name <=> other.name
end
end
def eql?(other)
self == other
end
end
```

How would you implement the `hash`

function such that `a.hash == b.hash`

in this case? In general I'd do:

```
def hash
@name.hash
end
```

But this does not include `pos_x`

and `pos_y`

.

Unfortunately this is mathematically impossible to define a valid hash function in this case.

Let a, b be two elements with equal positions, and different names. According to `eql?`

definition, this implies that `h(a) == h(b)`

. Since this is true for any names values, the hash function is to be independent on name attribute, which is however in contradiction with the second check. Hence there is no hash function for this `eql?`

definition. Sorry. :(

Update:

As noted by toro2k - your equality definition is not transitive. In general if a == b and b == c, it is required that a == c. According to your `eql?`

function:

```
{pos_x: 1, pos_y: 1, name: 'a'} == {pos_x: 1, pos_y: 1, name: 'b'}
{pos_x: 1, pos_y: 1, name: 'b'} == {pos_x: 2, pos_y: 2, name: 'b'}
```

but

```
{pos_x: 1, pos_y: 1, name: 'a'} != {pos_x: 2, pos_y: 2, name: 'b'}
```

That's the root of your problem here.