in reply to Iterating hashes safely and efficiently

As saouq correctly points out there is no difference between:

for my $key (keys %my_hash) {

and

for my $key (my @temp = keys %my_hash) {

Both create a temporary list. Both will be unaffected by changes to %my_hash.

If you want to make sure you cover keys added in the loop processing, and skip keys deleted by the loop processing, then you'll need to do something messy like:

my %hash = (a => 1, b => 2); my %seen_key = (); my $seen_key_count; do { $seen_key_count = keys %seen_key; foreach my $key (keys %hash) { # skip any entries deleted since we called keys next unless exists $hash{$key}; # skip any keys we have already seen next if $seen_key{$key}++; my $value = $hash{$key}; # do stuff with $value print "$key = $value\n"; # and mangle the hash $hash{c}="foo"; delete $hash{b}; }; } until ($seen_key_count == keys %seen_key);

But I'd agree with jarich and dragonchild. This smells like a design problem. If I needed to code anything like this I would have a very strong suspicion that there was something seriously wrong somewhere in the codebase. Rather than fix the symptom I would try and track down and eliminate the disease.

Could you give more of a description why this is necessary? Perhaps we could suggest an alternative solution.