Control Flow
## Learning Objectives
- Use conditional statements (if, unless)
- Work with given-when (smart match)
- Master loops (while, for, foreach)
- Control loop execution (next, last, redo)
- Understand loop labels
## if Statements
### Basic if
```perl
use strict;
use warnings;
my $age = 25;
if ($age >= 18) {
print "Adult\n";
}
```
### if-else
```perl
my $age = 15;
if ($age >= 18) {
print "Adult\n";
} else {
print "Minor\n";
}
```
### elsif
```perl
my $score = 85;
if ($score >= 90) {
print "A\n";
} elsif ($score >= 80) {
print "B\n";
} elsif ($score >= 70) {
print "C\n";
} else {
print "F\n";
}
```
### Statement Modifiers
```perl
use strict;
use warnings;
my $age = 25;
print "Adult\n" if $age >= 18;
my $status = $age >= 18 ? "adult" : "minor";
# For/while modifiers
print "Valid" if $x > 0 && $x < 100;
```
## unless Statement
### Basic unless
```perl
use strict;
use warnings;
my $age = 15;
unless ($age >= 18) {
print "Minor - cannot vote\n";
}
```
### unless-else
```perl
my $password = "secret";
unless ($password eq "secret") {
print "Access denied\n";
} else {
print "Access granted\n";
}
```
## given-when (Smart Match)
### Basic given-when
```perl
use strict;
use warnings;
use 5.010; # Smart match requires Perl 5.10+
my $grade = "B";
given ($grade) {
when ("A") { print "Excellent!\n" }
when ("B") { print "Good!\n" }
when ("C") { print "Average\n" }
default { print "Need improvement\n" }
}
```
### Smart Match Rules
```perl
use 5.010;
my $num = 42;
given ($num) {
when ($_ == 42) { print "The answer\n" } # Numeric equality
when (/^\d+$/) { print "Looks like a number\n" } # Regex match
when ([1, 2, 3]) { print "In list\n" } # Array contains
when (\%hash) { print "Hash reference\n" } # Is hash ref
default { print "Unknown\n" }
}
```
## while Loop
### Basic while
```perl
use strict;
use warnings;
my $count = 1;
while ($count <= 5) {
print "Count: $count\n";
$count++;
}
```
### do-while
```perl
my $count = 1;
do {
print "Count: $count\n";
$count++;
} while ($count <= 5);
# Always executes at least once
```
### while with each
```perl
my %ages = (
Alice => 30,
Bob => 25,
Carol => 35,
);
while (my ($name, $age) = each %ages) {
print "$name is $age years old\n";
}
```
## until Loop
### Basic until
```perl
use strict;
use warnings;
my $count = 1;
until ($count > 5) {
print "Count: $count\n";
$count++;
}
```
### do-until
```perl
my $count = 1;
do {
print "Count: $count\n";
$count++;
} until ($count > 5);
```
## for Loop
### C-style for
```perl
use strict;
use warnings;
for (my $i = 0; $i < 5; $i++) {
print "i = $i\n";
}
# Classic style
for (my $i = 0; $i <= $#array; $i++) {
print $array[$i];
}
```
### Infinite for
```perl
for (;;) {
print "Forever...\n";
last if some_condition();
}
```
## foreach Loop
### Basic foreach
```perl
use strict;
use warnings;
my @colors = ("red", "green", "blue");
foreach my $color (@colors) {
print "Color: $color\n";
}
```
### Default Variable $_
```perl
my @colors = ("red", "green", "blue");
foreach (@colors) {
print "Color: $_\n";
}
# Or using postfix
print $_ for @colors;
```
### Array Indices
```perl
my @colors = ("red", "green", "blue");
foreach my $idx (0 .. $#colors) {
print "$idx: $colors[$idx]\n";
}
# Or with each
while (my ($idx, $color) = each @colors) {
print "$idx: $color\n";
}
```
### Hash Iteration
```perl
my %data = (
name => "Alice",
age => 30,
city => "Boston",
);
foreach my $key (keys %data) {
print "$key => $data{$key}\n";
}
# Sorted keys
foreach my $key (sort keys %data) {
print "$key => $data{$key}\n";
}
```
## Loop Control
### next (Skip Iteration)
```perl
use strict;
use warnings;
foreach my $i (1 .. 10) {
next if $i % 2 == 0; # Skip even numbers
print "$i ";
}
# Prints: 1 3 5 7 9
```
### last (Exit Loop)
```perl
use strict;
use warnings;
foreach my $i (1 .. 100) {
if ($i == 10) {
print "Found 10!\n";
last; # Exit the loop
}
}
print "Done\n";
```
### redo (Restart Iteration)
```perl
use strict;
use warnings;
my $attempts = 0;
while ($attempts < 3) {
$attempts++;
print "Attempt $attempts\n";
if (some_condition()) {
redo; # Restart this iteration
}
}
```
### continue Block
```perl
use strict;
use warnings;
my $count = 0;
while ($count < 5) {
print "Before: $count\n";
} continue {
$count++;
print "After: $count\n";
}
```
## Loop Labels
### Named Loops
```perl
use strict;
use warnings;
OUTER: foreach my $i (1 .. 3) {
INNER: foreach my $j (1 .. 3) {
print "i=$i, j=$j\n";
last OUTER if $i == 2 && $j == 2;
}
}
```
## Conditional Flow
### and/or for Flow Control
```perl
use strict;
use warnings;
# Open file or die
open my $fh, "<", "file.txt" or die "Cannot open: $!";
# Process data or skip
$data = get_data() and process($data);
# Set default value
my $value = $input || "default";
# Chain operations
$obj->open()->read()->close();
```
### unless for Guard Clauses
```perl
sub process {
my ($data) = @_;
return unless defined $data;
return if $data eq "";
# Process...
}
```
## Summary
- `if`/`elsif`/`else` for conditional branching
- `unless` is negated `if` (if NOT)
- `given-when` for smart matching (Perl 5.10+)
- `while` loops while condition is true
- `until` loops until condition is true
- `for` is C-style with init/condition/step
- `foreach` iterates over lists
- `next` skips to next iteration
- `last` exits the loop entirely
- `redo` restarts current iteration
- Loop labels allow breaking outer loops
- Statement modifiers (`if`, `unless`, `for`) for concise code
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →