Skip to content

Commit

Permalink
perlfunc - update each documentation with foreach examples
Browse files Browse the repository at this point in the history
Also mention multiple-value foreach as a new alternative, and fix a hash dereference in a previous example.
  • Loading branch information
Grinnz authored and khwilliamson committed Oct 11, 2024
1 parent c669642 commit 77b7888
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ Cygwin <cygwin@cygwin.com> cygwin@cygwin.com <cygwin@cygwin.com>
Dagfinn Ilmari Mannsåker <ilmari@ilmari.org> Dagfinn Ilmari Mannsåker (via RT) <perlbug-followup@perl.org>
Dagfinn Ilmari Mannsåker <ilmari@ilmari.org> ilmari@vesla.ilmari.org <ilmari@vesla.ilmari.org>
Damian Conway <damian@conway.org> Damian Conway <damian@cs.monash.edu.au>
Dan Book <grinnz@grinnz.com> Dan <grinnz@grinnz.com>
Dan Dascalescu <bigbang7@gmail.com> Dan Dascalescu <ddascalescu+github@gmail.com>
Dan Faigin <unknown> Dan Faigin, Doug Landauer <unknown@longtimeago>
Dan Jacobson <jidanni@jidanni.org> Dan Jacobson <jidanni@hoffa.dreamhost.com>
Expand Down
24 changes: 21 additions & 3 deletions pod/perlfunc.pod
Original file line number Diff line number Diff line change
Expand Up @@ -2126,15 +2126,33 @@ 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 a C<foreach> loop rather than
C<while>-C<each>.
loop body.

This extends to using C<each> on the result of an anonymous hash or
array constructor. A new underlying array or hash is created each
time so each will always start iterating from scratch, eg:

# loops forever
while (my ($key, $value) = each @{ +{ a => 1 } }) {
while (my ($key, $value) = each %{ +{ a => 1 } }) {
print "$key=$value\n";
}

To avoid these problems resulting from the hash-embedded iterator, use a
L<C<foreach>|perlsyn/"Foreach Loops"> loop rather than C<while>-C<each>.
As of Perl 5.36, you can iterate over both keys and values directly with
a multiple-value C<foreach> loop.

# retrieves the keys one time for iteration
# iteration is unaffected by any operations on %hash within
foreach my $key (keys %hash) {
my $value = $hash{$key};
$hash{$key} = {keys => scalar keys %hash, outer => [%hash]};
some_function_that_may_mess_with(\%hash, $key, $value);
$hash{"new$key"} = delete $hash{$key};
}

# Perl 5.36+
foreach my ($key, $value) (%{ +{ a => 1 } }) {
print "$key=$value\n";
}

Expand Down

0 comments on commit 77b7888

Please sign in to comment.