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;