Map keys and values behavior

T

Thomas E Enebo

I am working on the JRuby project and I was running some of the tests
in samples/test.rb from main ruby-1.8.1 source. I ran across something
which seems like a bug to me (in the test). It is something like:

$y = {1, 2, 2, 4, 3, 6}
test_ok($y.keys, [1,2,3])
test_ok($y.values, [2,4,6])

Does ruby Maps really return keys and values in order of insertion?
That seems strange to me. Seems like the tests are missing a sort.

-Tom
 
C

Charles Mills

Thomas said:
I am working on the JRuby project and I was running some of the tests
in samples/test.rb from main ruby-1.8.1 source. I ran across something
which seems like a bug to me (in the test). It is something like:

$y = {1, 2, 2, 4, 3, 6}
test_ok($y.keys, [1,2,3])
test_ok($y.values, [2,4,6])

Does ruby Maps really return keys and values in order of insertion?

It might or it might not. But in general no.
That seems strange to me. Seems like the tests are missing a sort.
$ ruby -v
ruby 1.8.2 (2004-12-25) [i386-cygwin]
$ irb
irb(main):001:0> h = {1=>2, 2=>4, 3=>6}
=> {1=>2, 2=>4, 3=>6}
irb(main):002:0> h.keys
=> [1, 2, 3]
irb(main):003:0> h.values
=> [2, 4, 6]
irb(main):004:0> 3.hash
=> 7

In the above example the keys are in order, but that is only because
Ruby's hash's hashing algorithm. Fixnums hash to themself (Hash does
not call Fixnum#hash to save time, so 3.hash really == 3). Then (I
think, see st.c to verify) when the Hash is iterated over (to collect
the keys, values, etc) it is traversed in the order of the hash of the
keys.

Here is another example:
irb(main):003:0> "a".hash
=> 100
irb(main):004:0> "b".hash
=> 101
irb(main):005:0> h = {"a"=>1, "b"=>2}
=> {"a"=>1, "b"=>2}
irb(main):006:0> h.keys
=> ["a", "b"]
irb(main):007:0> h.values
=> [1, 2]
### Now try in different order ###
irb(main):008:0> h = {"b"=>2, "a"=>1}
=> {"a"=>1, "b"=>2}
irb(main):009:0> h.keys
=> ["a", "b"]
irb(main):010:0> h.values
=> [1, 2]

100 comes before 101.

-Charlie
 
C

Charles Mills

Charles said:
Thomas said:
I am working on the JRuby project and I was running some of the tests
in samples/test.rb from main ruby-1.8.1 source. I ran across something
which seems like a bug to me (in the test). It is something like:

$y = {1, 2, 2, 4, 3, 6}
test_ok($y.keys, [1,2,3])
test_ok($y.values, [2,4,6])

Does ruby Maps really return keys and values in order of
insertion?

It might or it might not. But in general no.
That seems strange to me. Seems like the tests are missing a sort.
$ ruby -v
ruby 1.8.2 (2004-12-25) [i386-cygwin]
$ irb
irb(main):001:0> h = {1=>2, 2=>4, 3=>6}
=> {1=>2, 2=>4, 3=>6}
irb(main):002:0> h.keys
=> [1, 2, 3]
irb(main):003:0> h.values
=> [2, 4, 6]
irb(main):004:0> 3.hash
=> 7

In the above example the keys are in order, but that is only because
Ruby's hash's hashing algorithm. Fixnums hash to themself (Hash does
not call Fixnum#hash to save time, so 3.hash really == 3).

Never mind, 3.hash == (3 << 1) + 1
Which equals LONG2FIX(3). So at the C level Hash doesn't have to call
Fixnum#hash because the Ruby representation is the hash of the Fixnum
or visa versa or something...
Then (I
think, see st.c to verify) when the Hash is iterated over (to collect
the keys, values, etc) it is traversed in the order of the hash of the
keys.

Here is another example:
irb(main):003:0> "a".hash
=> 100
irb(main):004:0> "b".hash
=> 101
irb(main):005:0> h = {"a"=>1, "b"=>2}
=> {"a"=>1, "b"=>2}
irb(main):006:0> h.keys
=> ["a", "b"]
irb(main):007:0> h.values
=> [1, 2]
### Now try in different order ###
irb(main):008:0> h = {"b"=>2, "a"=>1}
=> {"a"=>1, "b"=>2}
irb(main):009:0> h.keys
=> ["a", "b"]
irb(main):010:0> h.values
=> [1, 2]

100 comes before 101.

-Charlie
 
R

Robert Klemme

Thomas E Enebo said:
I am working on the JRuby project and I was running some of the tests
in samples/test.rb from main ruby-1.8.1 source. I ran across something
which seems like a bug to me (in the test). It is something like:

$y = {1, 2, 2, 4, 3, 6}
test_ok($y.keys, [1,2,3])
test_ok($y.values, [2,4,6])

Does ruby Maps really return keys and values in order of insertion?
No.

That seems strange to me. Seems like the tests are missing a sort.

Yes. Or you do a more complex type of test that ensures that all values
from the test array are contained in #values.

Kind regards

robert
 

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

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top