[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Hash order bug?

Javier Valencia

7/25/2006 1:43:00 PM

I have this piece of simple code:

----------------------------------------------
def foo
return 5
end

a = {:gr => false, :und => false, :det => true, :sta => false, :inv =>
false}
puts a.inspect
----------------------------------------------

when I execute it i get a totally unordered hash:

----------------------------------------------
ruby pro.rb
{:inv=>false, :gr=>false, :und=>false, :det=>true, :sta=>false}
----------------------------------------------

Now, i delete the foo function from the code (the foo function don't do
nothing at all), and i get a well ordered hash:

----------------------------------------------
ruby pro.rb
{:gr=>false, :und=>false, :det=>true, :sta=>false, :inv=>false}
----------------------------------------------


What's happening? all my code is behaving wrong because of that.

45 Answers

dblack

7/25/2006 1:45:00 PM

0

Nicolas Desprès

7/25/2006 1:47:00 PM

0

On 7/25/06, Javier Valencia <jvalencia@log01.org> wrote:
> I have this piece of simple code:
>
> ----------------------------------------------
> def foo
> return 5
> end
>
> a = {:gr => false, :und => false, :det => true, :sta => false, :inv =>
> false}
> puts a.inspect
> ----------------------------------------------
>
> when I execute it i get a totally unordered hash:
>

by definition a hash table is not ordered.

[...]

--
Nicolas Desprès

Javier Valencia

7/25/2006 1:48:00 PM

0

dblack@wobblini.net wrote:

> Hi --
>
> On Tue, 25 Jul 2006, Javier Valencia wrote:
>
>> I have this piece of simple code:
>>
>> ----------------------------------------------
>> def foo
>> return 5
>> end
>>
>> a = {:gr => false, :und => false, :det => true, :sta => false, :inv
>> => false}
>> puts a.inspect
>> ----------------------------------------------
>>
>> when I execute it i get a totally unordered hash:
>>
>> ----------------------------------------------
>> ruby pro.rb
>> {:inv=>false, :gr=>false, :und=>false, :det=>true, :sta=>false}
>> ----------------------------------------------
>>
>> Now, i delete the foo function from the code (the foo function don't
>> do nothing at all), and i get a well ordered hash:
>>
>> ----------------------------------------------
>> ruby pro.rb
>> {:gr=>false, :und=>false, :det=>true, :sta=>false, :inv=>false}
>> ----------------------------------------------
>>
>>
>> What's happening? all my code is behaving wrong because of that.
>
>
> Hashes are unordered. If you need an ordered collection, you'll need
> to use an array.
>
>
> David
>

Oh my god, i didn't know it, sorry. Is that a missing feature?

dblack

7/25/2006 1:53:00 PM

0

Javier Valencia

7/25/2006 2:22:00 PM

0

Nicolas Desprès wrote:

> On 7/25/06, Javier Valencia <jvalencia@log01.org> wrote:
>
>> I have this piece of simple code:
>>
>> ----------------------------------------------
>> def foo
>> return 5
>> end
>>
>> a = {:gr => false, :und => false, :det => true, :sta => false, :inv =>
>> false}
>> puts a.inspect
>> ----------------------------------------------
>>
>> when I execute it i get a totally unordered hash:
>>
>
> by definition a hash table is not ordered.
>
> [...]
>

Well, i don't mind ordering alphabetically, just to maintain their
construction order, like an array.
Anyway, thanks all for quick responses, hope to see that implemented in
core-ruby soon :)

Thanks

Kero van Gelder

7/25/2006 3:30:00 PM

0

[snip]
>>>> What's happening? all my code is behaving wrong because of that.
>>>
>>> Hashes are unordered. If you need an ordered collection, you'll need
>>> to use an array.
>>
>> Oh my god, i didn't know it, sorry. Is that a missing feature?
>
> Debate rages on this point :-) It's mostly a speed issue, I think.
> At least my memory is that Matz's latest statement was to the effect
> that he would do it if it could be done efficiently.
>
> The question came up during a lunch here at OSCON (with me, Jim
> Weirich, Pat Eyler, and a fellow named Nicolas whose last name I'm
> afraid I don't remember) as to whether making hashes ordered in a
> future Ruby would break any existing code. I think the answer is no,
> which is kind of interesting considering what a major change it would
> be. It's a case where the feature would be purely additive.

I guess there won't be many ppl using algorithms that use the *un*sorted
aspect of a Hash. Using Kernel#rand instead of Object#hash seems
better. printing a few hash-values suggest they're not that random anyway...

Other than that, would you sort the hash (or iterator) on its keys, its
values or insertion sequence?

NB: why did I read "addictive" at first pass? The question has been raised
more often; and I admit I have overridden Hash#keys (and Hash each_pair,
iirc) to achieve a (partially) sorted effect... The problem is that you can
not generally sort keys (specifically not symbols).

Paul Battley

7/25/2006 4:44:00 PM

0

On 25/07/06, dblack@wobblini.net <dblack@wobblini.net> wrote:
> The question came up during a lunch here at OSCON (with me, Jim
> Weirich, Pat Eyler, and a fellow named Nicolas whose last name I'm
> afraid I don't remember) as to whether making hashes ordered in a
> future Ruby would break any existing code. I think the answer is no,
> which is kind of interesting considering what a major change it would
> be. It's a case where the feature would be purely additive.

I think that would depend on whether {:a => 1, :b => 2} == {:b => 2,
:a => 1}. If that's the same, everything should be fine. If it's
different, I know that it would break a number of my tests, if nothing
else.

Paul.

William James

7/25/2006 6:47:00 PM

0

Javier Valencia wrote:
> dblack@wobblini.net wrote:
>
> > Hi --
> >
> > On Tue, 25 Jul 2006, Javier Valencia wrote:
> >
> >> I have this piece of simple code:
> >>
> >> ----------------------------------------------
> >> def foo
> >> return 5
> >> end
> >>
> >> a = {:gr => false, :und => false, :det => true, :sta => false, :inv
> >> => false}
> >> puts a.inspect
> >> ----------------------------------------------
> >>
> >> when I execute it i get a totally unordered hash:
> >>
> >> ----------------------------------------------
> >> ruby pro.rb
> >> {:inv=>false, :gr=>false, :und=>false, :det=>true, :sta=>false}
> >> ----------------------------------------------
> >>
> >> Now, i delete the foo function from the code (the foo function don't
> >> do nothing at all), and i get a well ordered hash:
> >>
> >> ----------------------------------------------
> >> ruby pro.rb
> >> {:gr=>false, :und=>false, :det=>true, :sta=>false, :inv=>false}
> >> ----------------------------------------------
> >>
> >>
> >> What's happening? all my code is behaving wrong because of that.
> >
> >
> > Hashes are unordered. If you need an ordered collection, you'll need
> > to use an array.
> >
> >
> > David
> >
>
> Oh my god, i didn't know it, sorry. Is that a missing feature?

No. What language has ordered hashes?

When you say
a = {:gr => false, :und => false, :det => true, :sta => false, :inv
=> false}
you are saying that you want to access the values in this fashion:
a[:und]
So the order in which they are stored is irrelevant.
If you want to access them this way
a[1]
then you set them up like this
[ false, false, true, false, false ]

If you want to get a sequence of values in a certain order:
a.values_at( :und, :det, :sta )

If you want to have your cake and eat it too, you could
use an association list:

>> as = [[:foo,22], [:bar,33], [:baz,44]]
=> [[:foo, 22], [:bar, 33], [:baz, 44]]
>> as.assoc(:bar)
=> [:bar, 33]
>> as.rassoc( 44 )
=> [:baz, 44]
>> as[0]
=> [:foo, 22]

If the list has a large number of elements, access will be slow.

Keith Gaughan

7/25/2006 7:34:00 PM

0

On Wed, Jul 26, 2006 at 03:50:05AM +0900, William James wrote:

> What language has ordered hashes?

Java, in the form of the TreeMap collection. The usefulness of them is
limited though, As anecdotal evidence, I've used it twice in the past
four years.

K.

--
Keith Gaughan - kmgaughan@eircom.net - http://tal...

Alex Young

7/25/2006 8:13:00 PM

0

Kero wrote:
> [snip]
>>>>> What's happening? all my code is behaving wrong because of that.
>>>> Hashes are unordered. If you need an ordered collection, you'll need
>>>> to use an array.
>>> Oh my god, i didn't know it, sorry. Is that a missing feature?
>> Debate rages on this point :-) It's mostly a speed issue, I think.
>> At least my memory is that Matz's latest statement was to the effect
>> that he would do it if it could be done efficiently.
>>
>> The question came up during a lunch here at OSCON (with me, Jim
>> Weirich, Pat Eyler, and a fellow named Nicolas whose last name I'm
>> afraid I don't remember) as to whether making hashes ordered in a
>> future Ruby would break any existing code. I think the answer is no,
>> which is kind of interesting considering what a major change it would
>> be. It's a case where the feature would be purely additive.
>
> I guess there won't be many ppl using algorithms that use the *un*sorted
> aspect of a Hash.
It's not that it's unordered, it's that it's anordered. The concept
doesn't apply. It's a bucket, not a queue. There are many, many
applications that don't care about entry order.

>Using Kernel#rand instead of Object#hash seems
> better. printing a few hash-values suggest they're not that random anyway...
The order is unpredictable and implementation dependent.

--
Alex