each
имеет встроенную скрытую глобальную переменную, которая может вам навредить. Если вам не нужно такое поведение, безопаснее просто использовать keys
.
Рассмотрим этот пример, где мы хотим сгруппировать наши пары k/v (да, я знаю, что printf
сделает это лучше):
#!perl
use strict;
use warnings;
use Test::More 'no_plan';
{ my %foo = map { ($_) x 2 } (1..15);
is( one( \%foo ), one( \%foo ), 'Calling one twice works with 15 keys' );
is( two( \%foo ), two( \%foo ), 'Calling two twice works with 15 keys' );
}
{ my %foo = map { ($_) x 2 } (1..105);
is( one( \%foo ), one( \%foo ), 'Calling one twice works with 105 keys' );
is( two( \%foo ), two( \%foo ), 'Calling two twice works with 105 keys' );
}
sub one {
my $foo = shift;
my $r = '';
for( 1..9 ) {
last unless my ($k, $v) = each %$foo;
$r .= " $_: $k -> $v\n";
}
for( 10..99 ) {
last unless my ($k, $v) = each %$foo;
$r .= " $_: $k -> $v\n";
}
return $r;
}
sub two {
my $foo = shift;
my $r = '';
my @k = keys %$foo;
for( 1..9 ) {
last unless @k;
my $k = shift @k;
$r .= " $_: $k -> $foo->{$k}\n";
}
for( 10..99 ) {
last unless @k;
my $k = shift @k;
$r .= " $_: $k -> $foo->{$k}\n";
}
return $r;
}
Отладка ошибки, показанной в приведенных выше тестах, в реальном приложении была бы ужасно болезненной. (Для лучшего вывода используйте Test::Differences
eq_or_diff
вместо is
.)
Конечно, one()
можно исправить, используя keys
для очистки итератора в начале и в конце подпрограммы. Если ты помнишь. Если все ваши коллеги помнят. Это совершенно безопасно, пока никто не забудет.
Не знаю, как вы, а я просто буду использовать keys
и values
.
person
daotoad
schedule
08.03.2010
keys HASH
илиvalues HASH
- person Daniel LeCheminant   schedule 07.03.2010