Hello choroba,
Yes, you’re right: despite the calls to delete, the for loop list doesn’t change, so it must be constructed before the first loop iteration.
Whereas using each I get an infinite loop:
use warnings;
use strict;
use Data::Dump qw(dd pp);
my %hash =
(
a => 11,
b => 12,
c => 13,
d => 14,
);
while (my ($key, $value) = each %hash)
{
print "key is $key, value is $value, hash is ", pp(\%hash), "\n";
delete $hash{$_} for qw( a b c d );
$hash{x} .= $key;
}
dd \%hash;
Output:
23:43 >perl 1148_SoPW.pl
key is c, value is 13, hash is { a => 11, b => 12, c => 13, d => 14 }
key is x, value is c, hash is { x => "c" }
key is x, value is cx, hash is { x => "cx" }
key is x, value is cxx, hash is { x => "cxx" }
key is x, value is cxxx, hash is { x => "cxxx" }
key is x, value is cxxxx, hash is { x => "cxxxx" }
key is x, value is cxxxxx, hash is { x => "cxxxxx" }
key is x, value is cxxxxxx, hash is { x => "cxxxxxx" }
key is x, value is cxxxxxxx, hash is { x => "cxxxxxxx" }
key is x, value is cxxxxxxxx, hash is { x => "cxxxxxxxx" }
...
Which isn’t surprising given the warning in the documentation for each:
If you add or delete a hash's elements while iterating over it, the effect on the iterator is unspecified; for example, entries may be skipped or duplicated--so don't do that. Exception: It is always safe to delete the item most recently returned by each()...
So it appears that sundialsvc4’s concern over memory is justified: for a large hash, the use of keys in a for loop will consume significantly more memory than the equivalent use of each. It seems strange to me that the documentation doesn’t highlight this — or did I just miss it somewhere?
Cheers,
|