Alex Rivera | Logout

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

Asked 2012-06-01T16:12:34.180
11

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?

Edit
Report

1 Answer

19

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()

answered 2012-06-01T16:19:31.343

Your Answer