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

Dear Monks,

I'm using given-when in a for loop:

use strict; use warnings; use 5.010; my @arr = (1, 2, 4); for (@arr) { print "$_: "; when (1) {print "1"; continue} when ($_ % 2 == 0) {print "divisible by 2"; continue} when ($_ % 4 == 0) {print ", divisible by 4"} say "\n------end this iteration"; }

Every time through the loop the last say statement executes--except the last time through the loop. Why? If I add a continue statement to the last when block, then the last line will execute for the last iteration of the loop.

Also, "Learning Perl 5th" says there is an implicit break at the end of each when block, but I get errors if I do this:

use strict; use warnings; use 5.010; my @arr = (1, 2, 4); for (@arr) { print "$_: "; when (1) {print "1"; break} when ($_ % 2 == 0) {print "divisible by 2"; break} when ($_ % 4 == 0) {print ", divisible by 4"; break} say "\n------end this iteration"; } --output:-- Can't "break" in a loop topicalizer at 1perl.pl line 10. 1: 1

Replies are listed 'Best First'.
Re: given-when last time through loop?
by moritz (Cardinal) on Nov 19, 2009 at 13:57 UTC
    Every time through the loop the last say statement executes--except the last time through the loop. Why?

    Your explicit call to continue inhibits the implicit call to break or next at the end of the when-block.

    Also, "Learning Perl 5th" says there is an implicit break at the end of each when block, but I get errors if I do this:

    It seems that if you use for instead of given as the outer control structure, it defaults to next instead of break.

    Perl 6 - links to (nearly) everything that is Perl 6.

      Hi,

      Thanks for the response.

      It seems that if you use for instead of given as the outer control structure, it defaults to next instead of break.

      Ok. I did read this in the perlsyn docs:

      On exit from the when block, there is an implicit next.

      ...but I found the 'on exit' language confusing. I thought they meant after the last when block. There should be a better example in the docs--that is a major change from using given-when on its own outside a loop.

      The docs could simply say, "Inside a for-loop, the when blocks end with an implicit next rather than an implicit break.

        I've now submitted this patch to the perl 5 porters, in the hope that it's a bit clearer:
        diff --git a/pod/perlsyn.pod b/pod/perlsyn.pod index d5fc4a7..4e1bc0a 100644 --- a/pod/perlsyn.pod +++ b/pod/perlsyn.pod @@ -679,7 +679,7 @@ string occurs in an array: } print "\@array contains $count copies of 'foo'\n"; -On exit from the C<when> block, there is an implicit C<next>. +At the end of all C<when> blocks, there is an implicit C<next>. You can override that with an explicit C<last> if you're only interested in the first match.

        So far I've found the porters very cooperative when it comes to doc patches, and I want to encourage everybody to submit patches when they find something that can be improved in the docs.

        Perl 6 - links to (nearly) everything that is Perl 6.