I am using each to iterate through a Perl hash:
while (my ($key,$val) = each %hash) {
...
}
Then something interesting happ
How big is this hash? How long does it take to iterate through it, such that you care about the timing of the access?
Just set a flag and do the action after the end of the iteration:
my $print_it;
while (my ($key,$val) = each %hash) {
$print_it = 1 if something_interesting_happens();
...
}
if ($print_it) {
foreach my $k (keys %hash) { print "$k => $hash{$k}\n" }
}
Although there's no reason not to use each in the printout code, too, unless you were planning on sorting by key or something.
Let's not forget that keys %hash is already defined when you enter the while loop. One could have simply saved the keys into an array for later use:
my @keys = keys %hash;
while (my ($key,$val) = each %hash) {
if (something_interesting_happens()) {
print "$_ => $hash{$_}\n" for @keys;
}
}
Downside:
%hash is modified (but then why would one use each in the first place?)Upside:
Not really. each is incredibly fragile. It stores iteration state on the iterated hash itself, state which is reused by other parts of perl when they need it. Far safer is to forget that it exists, and always iterate your own list from the result of keys %hash instead, because the iteration state over a list is stored lexically as part of the for loop itself, so is immune from corruption by other things.
Have you tried Storable's dclone to copy it? It would probably be something like this:
use Storable qw(dclone);
my %hash_copy = %{ dclone( \%hash ) };