Is Perl guaranteed to return consistently-ordered

2019-02-16 21:53发布

Given something like

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

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

Is Perl guaranteed to iterate over the keys in a consistent order if the hash is not altered?

3条回答
霸刀☆藐视天下
2楼-- · 2019-02-16 22:22

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.

查看更多
smile是对你的礼貌
3楼-- · 2019-02-16 22:34

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)

查看更多
做自己的国王
4楼-- · 2019-02-16 22:36

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.

查看更多
登录 后发表回答