in reply to Re: Bulk hash population order
in thread Bulk hash population order

So, in this simple example ...
my %lilhash = ( 'A' => 1, 'A' => 2, 'A' => 3 ); print $lilhash{'A'};
... you are saying that there's absolutely no guarantee that the code will print ...

3

?

Replies are listed 'Best First'.
Re^3: Bulk hash population order
by halley (Prior) on Nov 27, 2007 at 14:30 UTC
    I'm saying it's a bad assumption to make.

    We know that the perl interpreter will parse this equivalently to:

    my @hiddenlist = ( 'A', 1, 'A', 2, 'A', 3 ); my %lilhash; while (@hiddenlist) { my $hiddenkey = shift @hiddenlist; $lilhash{$hiddenkey} = shift @hiddenlist; } print $lilhash{'A'};
    However, the kinds of assumptions you are making have been made by many folks for years, and it's this kind of assumption that can stymy any interesting optimizations that the interpreter could do with bulk insertions.

    I just think it's a bad idea when the word "order" and the word "hash" come anywhere near each other to start making such assumptions. Regardless of how safe or well-entrenched the idiom may be, my advice is: the hash is unordered and the list is ordered and if you care about order, be explicit.

    --
    [ e d @ h a l l e y . c c ]

      Erm, the list is ordered, and it's the order the keys from that list are used to initialize the hash that's important. If you're going to allow multiple occurrences of any particular key in the initializing data then you're going to have to have a rule for which one "wins" when there are duplicates.

      The only sane rules are going to be "first occurrence wins" or "last occurrence wins" (either of which would allow some variant of the technique in question, so you'd do %hash = ( existing => "new value", %hash ) in bizzaro-perl). The latter of those rules is what perl uses and this is alluded to in perldata, unfortunately in passing rather than more explicitly; see the end of the section "List value constructors":

      Note that just because a hash is initialized in that order doesn't mean that it comes out in that order.

      So yes you shouldn't make any assumptions once it's gone in, but you are guaranteed (weakly, unfortunately) about the order pairs go in from a LIST.

      Update: Not to mention this is the "recommended" way to do default values when you're using a hashref to do named arguments to a sub. See pp185-187 of Perl Best Practices.