in reply to Re: OT: clearing a hash (was: TIMTOWTDI doesn't mean invent an outlandish approach (usually))
in thread TIMTOWTDI doesn't mean invent an outlandish approach (usually)

Ah, so that's why I was puzzled - the hint on each was there the first I wanted to know about deleting keys while iterating. But you said three of the following will not necessarily work:
  1. map { delete $hash{$_} } keys %hash;
  2. while (my ($k,$v) = each %hash) { delete $hash{$k} };
  3. for (keys %hash) { delete $hash{$_} };
  4. delete $hash{$_} for keys %hash;
With the each solution being valid that's one down, two to go, and now I'm more confused than before.. of the remaining three solutions, the for loops are identical except for syntactical details. So they must either both be valid or both invalid; then the map version must be valid and the for ones not. But I can't see any reason to conclude that any of them (all four) are not guaranteed to work.

Makeshifts last the longest.

Replies are listed 'Best First'.
Re: OT: clearing a hash (was: TIMTOWTDI doesn't mean invent an outlandish approach (usually))
by Abigail-II (Bishop) on Oct 13, 2003 at 11:36 UTC
    Number 1) is safe because in this case, a list of keys will be produced before the deletes are called. For 3) and 4), I though that 'for (keys %hash)' was special cased to iterate over the hash instead of producing a list (just like 'for (@array)' is special cased), but I can't find it in the documentation right now. Anyway, regardless whether it's special cased or not, 3) and 4) are fine as well, due to the exception of modifying a hash while iterating over it by deleting the last element returned by 'each' (since 'keys' and 'values' uses the same iterator).

    Abigail