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
覚えていれば。すべての同僚が覚えている場合。誰も忘れない限り、完全に安全です。
あなたのことはわかりませんが、 and の使用に固執しkeys
ますvalues
。