The following code leads to infinite recursion. If printed without Dumper then it works as expected. Why Dumper causes recursion?
use Data::Dumper;
my %hash1 = (
'key1' => ['val1']
);
while (my ($key, $value) = each %hash1) {
print Dumper \%hash1;
}
each to blame here. You're using it in your loop, and Data::Dumper uses it to iterate over the contents of hashes.
From the documentation of each (Emphasis added):
The iterator used by
eachis attached to the hash or array, and is shared between all iteration operations applied to the same hash or array. Thus all uses ofeachon a single hash or array advance the same iterator location. All uses ofeachare also subject to having the iterator reset by any use ofkeysorvalueson the same hash or array, or by the hash (but not array) being referenced in list context. This makeseach-based loops quite fragile: it is easy to arrive at such a loop with the iterator already part way through the object, or to accidentally clobber the iterator state during execution of the loop body. It's easy enough to explicitly reset the iterator before starting a loop, but there is no way to insulate the iterator state used by a loop from the iterator state used by anything else that might execute during the loop body. To avoid these problems, use aforeachloop rather thanwhile-each.
Like so:
#!/usr/bin/env perl
use warnings;
use strict;
use Data::Dumper;
my %hash1 = (
'key1' => ['val1']
);
foreach my $key (keys %hash1) {
print Dumper \%hash1;
}
Basically, don't use each unless you have full control over what's done with the hash in the body of the loop over its results.
The exact cause of an infinite loop is explained with this bit of documentation:
After
eachhas returned all entries from the hash or array, the next call toeachreturns the empty list in list context andundefin scalar context; the next call following that one restarts iteration.
The each loop in the Dumper() code first resets the internal iterator, and then repeats until it returns an empty list; then each is called again in the test of your while loop and starts afresh with the first (only) element of the hash, and repeats forever.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With