From: Charles Mills Date: 2005-02-09T03:55:07+09:00 Subject: Re: Map keys and values behavior Charles Mills wrote: > Thomas E Enebo wrote: > > 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