Is it safe in Perl to remove a key from a hash link when I loop on the same hash? And why?

I basically want to do this:

foreach my $key (keys $hash_ref) { Do stuff with my $key and $hash_ref # Delete the key from the hash delete $hash_ref->{$key}; } 

It's safe? And why?

+7
source share
2 answers

You do not repeat the hash, you repeat the list of keys returned by keys before you start the loop, because

 for my $key (keys %$hash_ref) { ... } 

roughly coincides with

 my @anon = keys %$hash_ref; for my $key (@anon) { ... } 

Removing from the hash does not cause any problems.


each , on the other hand, iterates over the hash. Each time he called, each returns a different element. However, it is still safe to delete current item!

 # Also safe while (my ($key) = each(%$hash_ref)) { ... delete $hash_ref->{$key}; ... } 

If you add or remove hash elements while iterating over it, entries may be skipped or duplicated, so don't do this. Exception: you can always delete an item that was recently returned by each ()

+15
source

This is safe because keys %hash provides the entire list once before you start iterating. foreach then continues to work on this pre-created list, regardless of what you change inside the actual hash.

It absorbs your memory because you save the entire list until you have done.

+3
source

All Articles