Каков самый безопасный способ перебора ключей хеша Perl?

Одна вещь, о которой вы должны iteration знать при использовании each, это hash то, что он побочный эффект .each добавления «состояния» к hash вашему хэшу (хэш должен помнить что hash такое «следующий» ключ). При perl использовании кода, подобного .each приведенным выше фрагментам, которые hash перебирают весь хэш за один hashes раз, обычно это не проблема. Тем .each не менее, вы столкнетесь hash с трудно отследимыми проблемами perl (я говорю из опыт ;), при iteration использовании each вместе с такими iterative утверждениями, как last или return для hash выхода из цикла while ... each до того, как iterative вы обработали все ключи.

В hash этом случае хеш запомнит, какие hashing ключи он уже вернул, и когда perl вы используете each на нем в digest следующий раз (возможно, в digest совершенно не связанном фрагменте код), он perl будет продолжаться в этой perl позиции.

Пример:

my %hash = ( foo => 1, bar => 2, baz => 3, quux => 4 );

# find key 'baz'
while ( my ($k, $v) = each %hash ) {
    print "found key $k\n";
    last if $k eq 'baz'; # found it!
}

# later ...

print "the hash contains:\n";

# iterate over all keys:
while ( my ($k, $v) = each %hash ) {
    print "$k => $v\n";
}

Это печатает:

found key bar
found key baz
the hash contains:
quux => 4
foo => 1

Что perl5 случилось с клавишами "бар" и hashing "баз"? Они все еще там, но второй iterative each начинается там, где остановился perl5 первый, и останавливается, когда hashing достигает конца хеша, поэтому perl мы никогда не видим их во digest втором цикле.

perl

hash

iteration

each

2022-07-17T01:46:58+00:00