Control Flow Patterns
Foreach with Next and Last
next skips to the next item, and last stops the loop early.
loop control
Loop control statements change how the current loop continues.
Foreach with Next and Last
foreach_next_last.pl
Replay: real traced execution (multi-file project)
use strict;
use warnings;
my $stop = 5;
my @values = (1, 2, 3, 4, 5, 6);
my $kept = 0;
my $seen = 0;
foreach my $value (@values) {
if ($value > $stop) {
last;
}
if ($value % 2 == 0) {
next;
}
$kept = $kept + $value;
$seen = $seen + 1;
}
print "stop=$stop\n";
print "seen=$seen\n";
print "kept=$kept\n";
use strict;
use warnings;
my $stop = 4;
my @values = (1, 2, 3, 4, 5, 6);
my $kept = 0;
my $seen = 0;
foreach my $value (@values) {
if ($value > $stop) {
last;
}
if ($value % 2 == 0) {
next;
}
$kept = $kept + $value;
$seen = $seen + 1;
}
print "stop=$stop\n";
print "seen=$seen\n";
print "kept=$kept\n";
use strict;
use warnings;
my $stop = 6;
my @values = (1, 2, 3, 4, 5, 6);
my $kept = 0;
my $seen = 0;
foreach my $value (@values) {
if ($value > $stop) {
last;
}
if ($value % 2 == 0) {
next;
}
$kept = $kept + $value;
$seen = $seen + 1;
}
print "stop=$stop\n";
print "seen=$seen\n";
print "kept=$kept\n";
$stop ← 5, @values ← 6, $kept ← 0, $seen ← 0
4my $stop→ 5 = 5; #@stop=4, 65my @values→ 6 = (1, 2, 3, 4, 5, 6);6my $kept→ 0 = 0;7my $seen→ 0 = 0;$kept ← 1, $seen ← 1
pass 1 of 69foreach my $value1 (@values6) {10 if ($value > $stop) {11 last;12 }13 if ($value % 2 == 0) {14 next;15 }16 $kept→ 1 = $kept + $value1;17 $seen→ 1 = $seen + 1;18}All 6 passes — pass 1 is the card above pass $value$stop$kept$seen1 1 — 0 → 1 0 → 1 2 2 — — — 3 3 — 1 → 4 1 → 2 4 4 — — — 5 5 — 4 → 9 2 → 3 6 6 5 — — if ($value % 2 == 0)
pass 1 of 212}13if ($value2 % 2 == 0) {14 next;15}if ($value % 2 == 0)
pass 2 of 212}13if ($value4 % 2 == 0) {14 next;15}if ($value > $stop)
9foreach my $value (@values) {10 if ($value6 > $stop5) {11 last;12 }print "stop=$stop ";
20print "stop=$stop5\n";21print "seen=$seen3\n";22print "kept=$kept9\n";outputstop=5 seen=3 kept=9
$stop ← 4, @values ← 6, $kept ← 0, $seen ← 0
4my $stop→ 4 = 4;5my @values→ 6 = (1, 2, 3, 4, 5, 6);6my $kept→ 0 = 0;7my $seen→ 0 = 0;$kept ← 1, $seen ← 1
pass 1 of 59foreach my $value1 (@values6) {10 if ($value > $stop) {11 last;12 }13 if ($value % 2 == 0) {14 next;15 }16 $kept→ 1 = $kept + $value1;17 $seen→ 1 = $seen + 1;18}All 5 passes — pass 1 is the card above pass $value$stop$kept$seen1 1 — 0 → 1 0 → 1 2 2 — — — 3 3 — 1 → 4 1 → 2 4 4 — — — 5 5 4 — — if ($value % 2 == 0)
pass 1 of 212}13if ($value2 % 2 == 0) {14 next;15}if ($value % 2 == 0)
pass 2 of 212}13if ($value4 % 2 == 0) {14 next;15}if ($value > $stop)
9foreach my $value (@values) {10 if ($value5 > $stop4) {11 last;12 }print "stop=$stop ";
20print "stop=$stop4\n";21print "seen=$seen2\n";22print "kept=$kept4\n";outputstop=4 seen=2 kept=4
$stop ← 6, @values ← 6, $kept ← 0, $seen ← 0
4my $stop→ 6 = 6;5my @values→ 6 = (1, 2, 3, 4, 5, 6);6my $kept→ 0 = 0;7my $seen→ 0 = 0;$kept ← 1, $seen ← 1
pass 1 of 69foreach my $value1 (@values6) {10 if ($value > $stop) {11 last;12 }13 if ($value % 2 == 0) {14 next;15 }16 $kept→ 1 = $kept + $value1;17 $seen→ 1 = $seen + 1;18}All 6 passes — pass 1 is the card above pass $value$kept$seen1 1 0 → 1 0 → 1 2 2 — — 3 3 1 → 4 1 → 2 4 4 — — 5 5 4 → 9 2 → 3 6 6 — — if ($value % 2 == 0)
pass 1 of 312}13if ($value2 % 2 == 0) {14 next;15}All 3 passes — pass 1 is the card above pass $value1 2 2 4 3 6 print "stop=$stop ";
20print "stop=$stop6\n";21print "seen=$seen3\n";22print "kept=$kept9\n";outputstop=6 seen=3 kept=9
Keep Odd Values Until Stop
$stopstarts at5.- The loop visits values from
1through6. - Even values use
next, so they are skipped. - Values above
5uselast, so the loop stops. - The kept total is
1 + 3 + 5, which is9. | Value | Action | Seen | Kept | | --- | --- | --- | --- | |1| add |1|1| |2| next |1|1| |3| add |2|4| |4| next |2|4| |5| add |3|9| |6| last |3|9|
Exercise: foreach_next_last.pl
Use next to skip even values, last after a stop value, and print seen and kept totals