continue#
Attach a block to a loop that runs after every iteration, just before the condition is re-tested.
continue is not a built-in function — it is a flow-control keyword.
In its one remaining sense it introduces the trailing block of a
while, until, or
foreach loop. The block runs at the end of each
iteration and whenever next transfers control out of the
main body, but not when last or redo do. It
plays the role that the third clause of a C for (init; cond; step)
loop plays in C.
Synopsis#
while (EXPR) { BODY } continue { STEP }
until (EXPR) { BODY } continue { STEP }
for VAR (LIST) { BODY } continue { STEP }
foreach VAR (LIST) { BODY } continue { STEP }
LABEL: while (EXPR) { BODY } continue { STEP }
What you get back#
continue is a statement, not an expression. It has no return value
and cannot appear in value position. The loop itself yields whatever
its context demands (nothing in void context, the last evaluated
expression under some constructs); the continue block does not
contribute to that.
Execution model#
For a loop with an attached continue block, each iteration runs in
this order:
Evaluate the condition (or take the next list element, for
foreach). If the loop should not run again, exit.Run the main body.
Run the
continueblock.Go back to step 1.
The three loop-control keywords interact with the continue block
differently:
next— jumps straight to step 3. Thecontinueblock is executed, then the condition is re-checked. This is the point of having acontinueblock: state that must advance on every iteration (a counter, a line number, a one-shot match reset) still advances when the body short-circuits vianext.last— leaves the loop entirely. Thecontinueblock is not executed.redo— restarts step 2 without re-checking the condition and without running thecontinueblock. Use it when the body needs another pass over the current iteration’s data (for example, after splicing in more input).
Omitting the continue block is equivalent to an empty one.
Examples#
A counter that advances even when the body skips:
my $n = 0;
for my $line (@lines) {
next if $line =~ /^\s*#/; # skip comments
process($line);
} continue {
$n++; # still counts skipped lines
}
print "scanned $n lines\n";
Equivalence to a C-style for loop — the two forms
below are the same, because Perl rewrites the C-style header as a
while with a continue block:
for (my $i = 1; $i < 10; $i++) { say $i }
my $i = 1;
while ($i < 10) {
say $i;
} continue {
$i++;
}
Resetting one-shot matches and line counters while streaming files
with <>:
while (<>) {
m?(fred)? && s//WILMA/;
m?(barney)? && s//BETTY/;
} continue {
print "$ARGV $.: $_";
close ARGV if eof; # reset $.
reset if eof; # reset ?pat?
}
The interaction with redo — note that continue runs on
the next path but not on the redo path:
while (<>) {
chomp;
if (s/\\$//) {
$_ .= <>;
redo unless eof; # merge continuation, re-enter body
} # continue block skipped on redo
process($_);
} continue {
$seen++; # counts completed records only
}
Edge cases#
No trailing block — bare
continue(without a following{ ... }) is a parse error in Perl 5.42. It used to be a valid statement inside theswitchfeature’sgiven/whenconstruct, where it fell through to the nextwhen. That feature was removed in 5.42;continuenow only has meaning as a trailing loop block.lastskips thecontinueblock. If the block holds cleanup you need on every path out, put the cleanup after the loop or in a scope guard, not incontinue.redoskips thecontinueblock. If thecontinueblock advances a counter, aredoiteration will not tick it — that is usually what you want (the iteration is not yet finished) but it can surprise code that relies on the counter matching the number of body entries.do { ... } whileis not a real loop —last,next, andredodo not work in it, and a trailingcontinueblock is a syntax error.Labeled loops —
LABEL:attaches to thewhile/for/foreachkeyword, not tocontinue.next LABELandlast LABELtarget the loop as a whole; thecontinueblock is part of that loop.A block by itself is a one-shot loop, so a bare
{ ... } continue { ... }parses and runs thecontinueblock once after the body — rarely useful, but legal.Foreach with aliasing — inside a
foreachloop the loop variable aliases the current list element. Thecontinueblock still runs with that alias in scope, so you can inspect or mutate the element there just as in the body.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
next— jump to thecontinueblock (if any) and re-test the condition; the one loop-control keyword that does run thecontinueblocklast— leave the loop entirely; skips thecontinueblockredo— restart the body without re-testing the condition; skips thecontinueblockreturn— leave the enclosing subroutine; also skips thecontinueblock because it leaves the loopbreak— companion keyword of the removedswitchfeature; like the baregiven/whenform ofcontinue, no longer available in 5.42