Perl гарантированно возвращает последовательно упорядоченные ключи хеша?
Учитывая что-то вроде
foreach (keys %myHash) {
... do stuff ...
}
foreach (keys %myHash) {
... do more stuff ...
}
Гарантируется ли Perl перебирать ключи в согласованном порядке, если хеш не изменяется?
3 ответа
Да От perldoc -f keys
:
Ключи возвращаются в случайном порядке. Фактический случайный порядок может быть изменен в будущих версиях Perl, ноон гарантированно будет того же порядка, что и
values
или жеeach
Функция производит (учитывая, что хеш не был изменен). Начиная с Perl 5.8.1, порядок разный даже для разных запусков Perl по соображениям безопасности (см. "Атаки алгоритмической сложности" вperldoc perlsec
).
(акцент мой)
Редактировать:
Хотя обычный хеш имеет последовательный порядок, в случае связанного хеша порядок ключей не очень хорошо определен, так как он контролируется пользователем!
Хотя порядок хэш-ключей не меняется, вам, вероятно, следует пересмотреть, почему вам нужно это сделать.
Возможно, вы можете обработать хеш за один проход вместо двух?
Вы должны сохранить ключи хеш-функции в массиве в качестве защитной практики программирования, если только размер данных не достаточно велик, чтобы их дублирование было проблемой. В качестве бонуса вы можете даже легко отсортировать список и обработать его в четко определенном порядке. Например,
my @keys = sort keys %myHash;
Это позволяет избежать каких-либо проблем с изменением хэша, так как ваш порядок массива никогда не изменится, если вы этого не захотите.
Если вы этого не сделаете, вам нужно быть очень осторожным, чтобы не делать ничего, что изменяет хеш, иначе порядок элементов изменится. Загляните в модуль Readonly, чтобы убедиться, что этот хэш никогда не изменяется.
Это довольно рискованное ожидание. Это, вероятно, будет, но зачем волноваться? Заранее извлекайте ключи, сохраняйте результат, затем перебирайте сохраненный результат. Тогда вы гарантированно получите доступ к ключам в том же порядке. Обрабатывать границы неуказанных деталей реализации опасно.
РЕДАКТИРОВАТЬ: пропустил "гарантию" в документе, но я все еще думаю, что опасно ожидать, что это никогда не изменится. Особенно, когда есть более разумные способы достижения тех же целей.