in reply to Why Doesn't each() DWIM?

From each docs:

When the hash is entirely read, a null array is returned in list context (which when assigned produces a false (0) value), and undef in scalar context. The next call to each after that will start iterating again. There is a single iterator for each hash, shared by all each, keys, and values function calls in the program; it can be reset by reading all the elements from the hash, or by evaluating keys HASH or values HASH.

Perhaps you don't like it, but it's documented.

If you want each to restart, you need to finish reading.

Put a  my $x = keys %hash; between the two loops, and it will work as you expect.

Replies are listed 'Best First'.
Re: Re: Why Doesn't each() DWIM?
by BrowserUk (Patriarch) on May 27, 2004 at 21:51 UTC

    If you have 5.8.3 or later, it's more efficient to use keys %hash; in a void context rather than a scalar context if you only want to reset the iterator.

    This avoids the need to calculate the number of keys in the hash, which for large and/or tied hashes can potentially be an expensive operation.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
Re:^2 Why Doesn't each() DWIM?
by Nkuvu (Priest) on May 27, 2004 at 21:15 UTC
    I think the question is more along the lines of "why does it work this way" as opposed to "does it work this way" or "is this behavior documented". Can you think of a good scenario where not resetting each is a desired behavior?
Re: Re: Why Doesn't each() DWIM?
by enoch (Chaplain) on May 27, 2004 at 21:15 UTC

    Yea.

    I am just wondering if there is a reason Perl won't do it for me? Why isn't there a little Do What I Mean in there.

    Is there a technical reason why that piece of DWIMmery would be considered harmful at some edge case?

      Perl already does what I mean in this case. If it did what you wanted, my expectations would be violated. Also, let's say that at the end of a loop the iterator on each() was reset, how would you get the behavior where it wasn't reset when you need it?
        how would you get the behavior where it wasn't reset when you need it?

        ++

        Good point

      Is there a technical reason why that piece of DWIMmery would be considered harmful at some edge case?

      I can think of one. Whether it is right or not is another matter :)

      There would be times when you wanted to return to your position in the hash. If the iterator (or hashkey pointer) was reset everytime the program left a control loop, you would have to save it in a variable and then restore it each time you went into another control structure.

      I don't see this as being a bad thing - other languages do it like this. I also don't know why it wasn't done this way rather than the way it currently is.

      Having said that, I have found this to be a problem before, but some careful data structure design worked around it just fine.

      ____________________
      Jeremy
      I didn't believe in evil until I dated it.