senduran has asked for the wisdom of the Perl Monks concerning the following question:

Why doesn't this work as expected? The contents of $hash seem to disappear after the first loop:

my $hash = { one => 1 }; PRED: foreach my $i (0..5) { print "PRED $i\n"; while (my ($key, $val) = each %{$hash}) { print " - $key => $val\n"; next PRED; } exit; }

But this does? Doing some operation on $hash keeps the content alive:

my $hash = { one => 1 }; PRED: foreach my $i (0..5) { scalar(keys %{$hash}); print "PRED $i\n"; while (my ($key, $val) = each %{$hash}) { print " - $key => $val\n"; next PRED; } exit; }

I don't get it. Can someone explain what is going on?

Replies are listed 'Best First'.
Re: What's happening to this hash?
by GrandFather (Saint) on Jun 07, 2007 at 09:40 UTC

    each is used under the hood to provide the result from keys with the result that the iterator used by each is reset. Your hash has only one entry so in the first case you only get one iteration of the while "if" (bizare construction btw!) before each hits the end of the list. In the second case you keep resetting the iterator by using keys so the if/while always sees a true value because it always accesses the first element in the hash.


    DWIM is Perl's answer to Gödel
Re: What's happening to this hash?
by varian (Chaplain) on Jun 07, 2007 at 09:46 UTC
    When you execute a keys or a values function it resets the internal hash iterator used by each on that hash. That's why the second example works as one would expect.