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};
}
Is it safe? 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};
}
Is it safe? And why?
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()
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.