Is Perl guaranteed to return consistently-ordered hash keys?

后端 未结 3 944
生来不讨喜
生来不讨喜 2021-01-12 01:57

Given something like

foreach (keys %myHash) {
   ... do stuff ...
}

foreach (keys %myHash) {
   ... do more stuff ...
}

Is Perl guaranteed

相关标签:
3条回答
  • 2021-01-12 02:41

    Yes. From perldoc -f 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). Since Perl 5.8.1 the ordering is different even between different runs of Perl for security reasons (see "Algorithmic Complexity Attacks" in perldoc perlsec).

    (emphasis mine)

    0 讨论(0)
  • 2021-01-12 02:41

    This is a pretty dicey expectation. It probably will, but why worry? Fetch keys in advance, save the result, then iterate over the saved result. Then, you're guaranteed to access keys in same order. Working around the edges of unspecified implementation details is dangerous.

    EDIT: Missed the "guarantee" in the doc, but I still think it's dangerous to expect this will never change. Especially when there are saner ways to achieve the same ends.

    0 讨论(0)
  • 2021-01-12 03:02

    Edit:

    Although a normal hash has a consistent ordering, in the case of a tied hash the order of the keys is not well defined, as it is user-controlled!


    Although the hash key order does not change, you probably should reconsider why you need to do this.

    Perhaps you can process the hash in one pass instead of two?

    You should save the hash keys into an array as a defensive programming practice, unless the size of the data is large enough that duplicating it would be a problem. As a bonus, you can even sort the list easily and process in the hash in a well defined order. E.g.,

       my @keys = sort keys %myHash;
    

    This avoids any problems with modifying the hash, since your array order will never change unless you want it to.

    If you do not do this, you need to be very careful not to do anything that changes the hash, otherwise the order of the elements will change. Look into the Readonly module to ensure that this hash is never modified.

    0 讨论(0)
提交回复
热议问题