rrwo has asked for the wisdom of the Perl Monks concerning the following question:

Here's a question for Perl-core gurus:

If during the execution of a Perl script on a specific machine during a specific session, I have a hash that I have not made changes to, can I be sure that each time I produce an array

@list = (keys %hash);

that list will always be in the same (consistent) order while that script is running on that machine in a specific version of Perl?

(I don't care if the order is different for different versions of Perl, on different platforms; just that while a script is running during a particular session that the order be consistent.)

Replies are listed 'Best First'.
Re: Consistent order of (keys %hash)?
by Fletch (Bishop) on Nov 09, 2001 at 00:52 UTC

    Quoting chapter and verse from perldoc -f keys:

    ... number of keys.) The keys are returned in an apparently random order. The actual random order is subject to change in future versions of perl, but it is guaranteed to be the same order as either the "values" or "each" function produces (given that the hash has not been modified). ...

    So I'd say the answer is probably yes. Of course you can always store off the list once and use a slice to extract the corresponding values in the same order whenever you need.

Re: Consistent order of (keys %hash)?
by perrin (Chancellor) on Nov 09, 2001 at 01:08 UTC
    The answer is yes. However, this is not consistent between different hashes, so be careful. In this message, gbarr demonstrates that assign order can change the order of keys.
      Agreed.

      To the original poster: relying on an implementation detail like this to do something useful is a bad idea. Especially when it's clearly stated (or at least implied) in the language documentation that the order shouldn't be relied on.

      It might be fine for a JAPH or a 1-liner, but using this feature anywhere important is foolish; if the implementation changes, or someone ties the hash an application could screw up...

        The fact that repeated calls to keys %hash always returns the exact same thing right down to the order of the keys isn't an implementation detail; it is documented behavior. If you don't modify %hash, then you can be assured that the order of items returned by keys, values, and each is consistant no matter how many times you call them.

        A tied hash that violates this rule would be rather strange. Even DB* hashes obey this rule.

        It is an important rule because it allows code like:     %copy{keys %hash}= values %hash; to work (which efficiently merges %hash into %copy).

                - tye (but my friends call me "Tye")
Re: Consistent order of (keys %hash)?
by dragonchild (Archbishop) on Nov 09, 2001 at 03:16 UTC
    Of course, your question leads me to think that you're not using the correct data structure. It might behoove you to use a tied hash that stores its keys in some internal data structure. Then, you can redefine the KEYS, VALUES, and EACH functions (or whatever they're called) to access that array vs. accessing the hash itself. This would allow you to guarantee, beyond a scintilla (SAT!!) of a doubt, that the order of keys would always be the same. In fact, it would allow you to guarantee the following, too!
    # Put the first ten things in my @first_ten = (keys %hash)[0 .. 9]; # add some values to %hash my @first_ten2 = (keys %hash)[0 .. 9]; $first_ten[3] eq $first_ten2[3]
    Which could be useful, I admit.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Re: Consistent order of (keys %hash)?
by Masem (Monsignor) on Nov 09, 2001 at 01:42 UTC
    As others have pointed out, you cannot guarentee order from keys alone. Of course, except for very large hashes, @list = sort keys %hash; will do exactly what you need, portable on perl versions and OSes. Of course, if you have a very large hash to make sorting prohibative, and you are worried about order, you probably have the wrong data structure (You probably want a list of hashes).

    -----------------------------------------------------
    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
    "I can see my house from here!"
    It's not what you know, but knowing how to find it if you don't know that's important