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
and values
。