@@ -2126,15 +2126,33 @@ accidentally clobber the iterator state during execution of the loop body.
2126
2126
It's easy enough to explicitly reset the iterator before starting a loop,
2127
2127
but there is no way to insulate the iterator state used by a loop from
2128
2128
the iterator state used by anything else that might execute during the
2129
- loop body. To avoid these problems, use a C<foreach> loop rather than
2130
- C<while>-C<each>.
2129
+ loop body.
2131
2130
2132
2131
This extends to using C<each> on the result of an anonymous hash or
2133
2132
array constructor. A new underlying array or hash is created each
2134
2133
time so each will always start iterating from scratch, eg:
2135
2134
2136
2135
# loops forever
2137
- while (my ($key, $value) = each @{ +{ a => 1 } }) {
2136
+ while (my ($key, $value) = each %{ +{ a => 1 } }) {
2137
+ print "$key=$value\n";
2138
+ }
2139
+
2140
+ To avoid these problems resulting from the hash-embedded iterator, use a
2141
+ L<C<foreach>|perlsyn/"Foreach Loops"> loop rather than C<while>-C<each>.
2142
+ As of Perl 5.36, you can iterate over both keys and values directly with
2143
+ a multiple-value C<foreach> loop.
2144
+
2145
+ # retrieves the keys one time for iteration
2146
+ # iteration is unaffected by any operations on %hash within
2147
+ foreach my $key (keys %hash) {
2148
+ my $value = $hash{$key};
2149
+ $hash{$key} = {keys => scalar keys %hash, outer => [%hash]};
2150
+ some_function_that_may_mess_with(\%hash, $key, $value);
2151
+ $hash{"new$key"} = delete $hash{$key};
2152
+ }
2153
+
2154
+ # Perl 5.36+
2155
+ foreach my ($key, $value) (%{ +{ a => 1 } }) {
2138
2156
print "$key=$value\n";
2139
2157
}
2140
2158
0 commit comments