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
It is safe, because keys %hash
provides entire list once, before you start iterating. foreach
then continues to work on this pre-generated list, no matter what you change inside actual hash.
It eats up your memory though, because you keep entire list until you've done.
You're not iterating over the hash, you're iterating over the list of keys returned by keys
before you even started looping. Keep in mind that
for my $key (keys %$hash_ref) {
...
}
is roughly the same as
my @anon = keys %$hash_ref;
for my $key (@anon) {
...
}
Deleting from the hash causes no problem whatsoever.
each, on the other, does iterate over a hash. Each time it's called, each
returns a different element. Yet, it's still safe to delete
the current element!
# Also safe
while (my ($key) = each(%$hash_ref)) {
...
delete $hash_ref->{$key};
...
}
If you add or delete a hash's elements while iterating over it, 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()