Control Flow

8.1 Conditionals

if ($score >= 90) {
    say 'A';
} elsif ($score >= 80) {     # note: elsif, not elseif / else if
    say 'B';
} else {
    say 'C';
}

unless ($logged_in) { say 'Please log in' }    # the opposite of if (avoid unless/else)

say 'Adult' if $age >= 18;                     # statement modifiers
say 'Minor' unless $age >= 18;
my $grade = $score >= 50 ? 'pass' : 'fail';    # ternary

8.2 Loops

for (my $i = 0; $i < 5; $i++) { say $i }       # C-style for
for my $i (1..5) { say $i }                    # range loop
my $n = 5;
while ($n > 0) { $n-- }
until ($n >= 5) { $n++ }                       # loop until the condition is true
do { $n-- } while ($n > 0);                    # body runs at least once (note: a do block isn't a true loop: next/last don't work)
say $_ for 1..3;                               # statement modifier loops
$n++ while $n < 10;

8.3 Loop Control

LINE: while (my $line = <STDIN>) {
    next LINE if $line =~ /^#/;     # skip to the next iteration
    last LINE if $line =~ /^END/;   # exit the loop
    redo LINE if ...;               # restart the iteration without re-evaluating the condition
    process($line);
}

OUTER: for my $i (1..3) {
    for my $j (1..3) {
        next OUTER if $j == 2;      # labels control outer loops
        say "$i,$j";
    }
}

8.4 Switch-Like Constructs

# given/when and smartmatch (~~) are deprecated (5.38) and scheduled for removal: avoid them.
# Idiomatic alternatives:
for ($command) {
    if (/^start$/) { start(); last }
    if (/^stop$/)  { stop();  last }
    say "Unknown: $_";
}

my %dispatch = (                              # dispatch table (preferred)
    start => \&start,
    stop  => \&stop,
    help  => sub { say 'Usage: ...' },
);
($dispatch{$command} // sub { say "Unknown: $command" })->();

8.5 Blocks and Other Constructs

{   # bare block: a loop that runs once (last works inside it), plus a new lexical scope
    my $temp = 42;
    last if $temp > 40;
}
my $value = do { local $/; <$fh> };           # do BLOCK returns the last expression
die "Fatal error\n" if $broken;
exit 0;