[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Map keys and values behavior

Thomas E Enebo

2/8/2005 6:04:00 PM

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

--
+ http://www.tc.umn.... +---- mailto:enebo@acm.org ----+
| Thomas E Enebo, Protagonist | "A word is worth a thousand |
| | pictures" -Bruce Tognazzini |1


3 Answers

Charles Mills

2/8/2005 6:44:00 PM

0


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). 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

Charles Mills

2/8/2005 6:54:00 PM

0


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

Robert Klemme

2/9/2005 9:02:00 AM

0


"Thomas E Enebo" <enebo@acm.org> schrieb im Newsbeitrag
news:20050208180232.GH20797@garnet.tc.umn.edu...
> 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