2009-08-10 1 views
8

Учитывая то, какЯвляется ли Perl гарантией возврата неизменно упорядоченных хеш-ключей?

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

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

Является ли Perl гарантированно перебирать ключи в последовательном порядке, если хэш не изменяется?

+0

Просто из любопытства - для чего вам нужно это имущество? – hillu

+1

Кто голосует за все и что угодно? – erjiang

ответ

26

Yes. От perldoc -f keys:

Ключи возвращаются в явно произвольном порядке. Фактический случайный порядок может быть изменен в будущих версиях perl, но гарантированно будет иметь тот же порядок, что и функция values или each (учитывая, что хэш не был изменен). Поскольку Perl 5.8.1 упорядочение отличается даже между разными прогонами Perl по соображениям безопасности (см. «Алгоритмические атаки на сложность» в perldoc perlsec).

(курсив мой)

+12

+1 Было бы здорово, если бы люди, по крайней мере, попытались прочитать отличную документацию, которая поставляется с Perl. –

-2

Это довольно рискованный ожидание. Это, вероятно, будет, но зачем беспокоиться? Выбирайте ключи заранее, сохраняйте результат, затем перебирайте сохраненный результат. Затем вам гарантируется доступ к ключам в том же порядке. Опасность заключается в том, что работа вокруг краев деталей неопределенной реализации.

EDIT: Отсутствует «гарантия» в документе, но я по-прежнему считаю опасным ожидать, что это никогда не изменится. Особенно, когда есть более разумные способы достижения тех же целей.

+2

Почему страшные цитаты вокруг «гарантии»?Это (а) очень четко сказано; (b) вряд ли изменится, потому что его важно для «ключей» и «значений» вернуться в том же порядке, так что эти два могут быть скоррелированы, если вы не можете использовать «каждый». – derobert

0

Edit:

Хотя нормальный хэш имеет последовательный порядок, в случае tied hash порядок ключей не определен, как это контролируемый пользователь!


Хотя порядок хеш-ключей не изменяется, вероятно, вам следует пересмотреть, зачем вам это нужно.

Возможно, вы можете обработать хэш за один проход вместо двух?

Вы должны сохранить ключи хэша в массив как защитную практику программирования, если размер данных не будет достаточно большим, чтобы дублирование было проблемой. В качестве бонуса вы можете даже отсортировать список легко и обрабатывать хэш в четко определенном порядке. НАПРИМЕР,

my @keys = sort keys %myHash; 

Это позволяет избежать каких-либо проблем с модификацией хэша, так как ваш заказ массив никогда не изменится, если вы не хотите.

Если вы этого не сделаете, вам нужно быть очень осторожным, чтобы не делать ничего, что меняет хэш, иначе порядок элементов изменится. Посмотрите на модуль Readonly, чтобы этот хэш никогда не менялся.

+0

Я не понимаю - почему вы должны защищаться от тестируемой, документированной и гарантированной работы? Это кажется таким же глупым, как использование текстового редактора и вызов файла -> Safe дважды в строке, в надежде, что если первый из них завершится неудачно, второй будет успешным. – moritz

+2

@moritz: проблема не в том, что Perl изменяет порядок ключей (или нет), это значит, что порядок может измениться, если хэш будет изменен. Этот ответ предлагает оборонительную тактику программирования (отдельный массив плюс Readonly) для будущего обслуживания кодовой базы OP и не имеет ничего общего с внутренними компонентами Perl. –

+3

Если нет серьезных причин для производительности, я стараюсь всегда сортировать. Часто укушенный кодом, который неявно ожидает определенного порядка и начинает таинственно таинственно, когда кажущиеся несвязанные изменения приводят к другому порядку ключей. – ysth

Смежные вопросы