Charles Mills
2/8/2005 6:54:00 PM
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