Array#hash bug?

M

Mark Hubbart

Hi,
I was messing around with recursive arrays and I came across this:

mark@imac% cat hash.rb
a = []
a[0] = a
puts a.hash
mark@imac% ruby -v hash.rb
ruby 1.9.0 (2004-04-11) [powerpc-darwin]
hash.rb:3:in `hash': stack level too deep (SystemStackError)
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
... 44888 levels...
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3

... looks like a bug?

cheers,
--Mark
 
Z

Zsban Ambrus

You might count this as a bug, but it is documented.

In ToDo of ruby-1.8.1, there is this line:

- hash etc. should handle self referenceing array/hash

Hi,
I was messing around with recursive arrays and I came across this:

mark@imac% cat hash.rb
a = []
a[0] = a
puts a.hash
mark@imac% ruby -v hash.rb
ruby 1.9.0 (2004-04-11) [powerpc-darwin]
hash.rb:3:in `hash': stack level too deep (SystemStackError)
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
... 44888 levels...
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3

... looks like a bug?

cheers,
--Mark

ambrus
 
R

Robert Klemme

Mark Hubbart said:
Hi,
I was messing around with recursive arrays and I came across this:

mark@imac% cat hash.rb
a = []
a[0] = a
puts a.hash
mark@imac% ruby -v hash.rb
ruby 1.9.0 (2004-04-11) [powerpc-darwin]
hash.rb:3:in `hash': stack level too deep (SystemStackError)
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
... 44888 levels...
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3

.. looks like a bug?

Hm, I'd say that for efficiency reasons loop detection in object graphs of
arrays is not done and thus it's a bug you'll have to live with. After
all, how often do you need self referencing containers?

robert
 
M

Mark Hubbart

Mark Hubbart said:
Hi,
I was messing around with recursive arrays and I came across this:

mark@imac% cat hash.rb
a = []
a[0] = a
puts a.hash
mark@imac% ruby -v hash.rb
ruby 1.9.0 (2004-04-11) [powerpc-darwin]
hash.rb:3:in `hash': stack level too deep (SystemStackError)
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
... 44888 levels...
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3

.. looks like a bug?

Hm, I'd say that for efficiency reasons loop detection in object
graphs of
arrays is not done and thus it's a bug you'll have to live with. After
all, how often do you need self referencing containers?

Apparently if I *do* need self referencing arrays, I can't use #hash on
them. Unless I redefine it so it works properly.

Anyway, I realized that the documentation for Array#hash is messed up.
It claims (or at least implies) that #eql? uses #hash to compare
values. I was assuming that a bug in #hash would make comparisons mess
up. I was wrong :)

irb(main):047:0> [1].eql? [2,1]
=> false
irb(main):048:0> [1].hash == [2,1].hash
=> true

hashes are definitely not unique :)

--Mark
 
Y

Yukihiro Matsumoto

In message "Re: Array#hash bug?"

|Anyway, I realized that the documentation for Array#hash is messed up.
|It claims (or at least implies) that #eql? uses #hash to compare
|values. I was assuming that a bug in #hash would make comparisons mess
|up. I was wrong :)

Which document did you read? ri says:

call-seq:
array.eql?(other) => true or false

Returns <code>true</code> if _array_ and _other_ are the same object,
or are both arrays with the same content.

Array#eql? does not use Array#hash at all for comparison. Hash
assumes hash values to be same when eql? is true (but not reverse).

matz.
 
R

Robert Klemme

Mark Hubbart said:
Mark Hubbart said:
Hi,
I was messing around with recursive arrays and I came across this:

mark@imac% cat hash.rb
a = []
a[0] = a
puts a.hash
mark@imac% ruby -v hash.rb
ruby 1.9.0 (2004-04-11) [powerpc-darwin]
hash.rb:3:in `hash': stack level too deep (SystemStackError)
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
... 44888 levels...
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3:in `hash'
from hash.rb:3

.. looks like a bug?

Hm, I'd say that for efficiency reasons loop detection in object
graphs of
arrays is not done and thus it's a bug you'll have to live with. After
all, how often do you need self referencing containers?

Apparently if I *do* need self referencing arrays, I can't use #hash on
them. Unless I redefine it so it works properly.

Yes. But do you need them? And if so, to which end?
Anyway, I realized that the documentation for Array#hash is messed up.
It claims (or at least implies) that #eql? uses #hash to compare
values. I was assuming that a bug in #hash would make comparisons mess
up. I was wrong :)

irb(main):047:0> [1].eql? [2,1]
=> false
irb(main):048:0> [1].hash == [2,1].hash
=> true

hashes are definitely not unique :)

That's the nature of hash values. Always was. :)

robert
 
M

Mark Hubbart

In message "Re: Array#hash bug?"

|Anyway, I realized that the documentation for Array#hash is messed up.
|It claims (or at least implies) that #eql? uses #hash to compare
|values. I was assuming that a bug in #hash would make comparisons mess
|up. I was wrong :)

Which document did you read? ri says:

call-seq:
array.eql?(other) => true or false

Returns <code>true</code> if _array_ and _other_ are the same object,
or are both arrays with the same content.

Array#eql? does not use Array#hash at all for comparison. Hash
assumes hash values to be same when eql? is true (but not reverse).

I was just stupid :) I misinterpreted the ri entry for Array#hash:

Compute a hash-code for this array. Two arrays with the same
content will have the same hash code (and will compare using
+eql?+).

Actually, this entry is completely true, much to my surprise; I just
read it completely wrong. :/

--Mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,825
Members
47,371
Latest member
Brkaa

Latest Threads

Top