each
hat eine Buit-in, versteckte globale Variable, die Sie verletzen kann. Wenn Sie dieses Verhalten nicht benötigen, ist es sicherer, einfach keys
zu verwenden.
Betrachten Sie dieses Beispiel, wo wir Gruppe unserer k/v Paare wollen (ja, ich weiß printf
würde dies besser tun):
#!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;
}
die Fehler in den Tests, die oben in einer realen Anwendung gezeigt Debuggen wären schrecklich schmerzhaft. (Für eine bessere Ausgangs Verwendung Test::Differences
eq_or_diff
statt is
.)
Natürlich one()
kann mit keys
befestigt werden, um den Iterator am Anfang und Ende des Unterprogramms zu löschen. Falls du dich erinnerst. Wenn alle Ihre Mitarbeiter sich erinnern. Es ist vollkommen sicher, solange niemand vergisst.
Ich weiß nicht über Sie, aber ich bleibe einfach bei der Verwendung von keys
und values
.
Ich würde mir vorstellen, dass die üblichen Workarounds die Bewertung von 'Schlüssel HASH' oder' Werte HASH' enthalten. –