Control Structures

The simplest flow of control is linear—one statement follows the next in a straight line to the end of the program. Since this is far too limiting for most situations, languages provide ways to alter the control flow.

Selection

Selection executes one set of actions out of many possible sets. The selection control structures are `if`, `unless`, and `given`.

The if statement

The `if` statement checks a condition and executes its associated block only if that condition is true. The condition can be any expression that evaluates to a truth value. Parentheses around the condition are optional:

```if \$blue {
print "True Blue.";
}```

The `if` statement can also have an unlimited number of `elsif` statements that check additional conditions when the preceding conditions are false. The final `else` statement executes if all preceding `if` and `elsif` conditions are false:

```if \$blue {
print "True Blue.";
} elsif \$green {
print "Green, green, green they say...";
} else {
print "Colorless green ideas sleep furiously.";
}```

The unless statement

The `unless` statement is the logical opposite of `if`. Its block executes only when the tested condition is false:

```unless \$fire {
print "All's well.";
}```

There is no `elsunless` statement, though `else` works with `unless`.

The switch statement

The switch statement selects an action by comparing a `given` expression, the switch, to a series of `when` statements, the cases. When a case matches the switch, its block is executed:

```given \$bugblatter {
when Beast::Trall { close_eyes(  ); }
when 'ravenous'   { toss('steak'); }
when .feeding     { sneak_past(  ); }
when /grrr+/      { cover_ears(  ); }
when 2            { run_between(  ); }
when (3..10)      { run_away(  ); }

}```

If these comparisons are starting to look familiar, they should. The set of possible relationships between a `given` and a `when` are exactly the same as the left and right side of a smart match operator (`~~`). The `given` aliases its argument to `\$_`.[14]

The `when` is a defaulting construct that does an implicit smart match on `\$_`. The result is the same as if you typed:

```given \$bugblatter {
when \$_ ~~ Beast::Trall { close_eyes(  ); }
when \$_ ~~ 'ravenous'   { toss('steak'); }
when \$_ ~~ .feeding     { sneak_past(  ); }
when \$_ ~~ /grrr+/      { cover_ears(  ); }
when \$_ ~~ 2            { run_between(  ); }
when \$_ ~~ (3..10)      { run_away(  ); }
}```

but much more convenient. In general, only one case is ever executed. Each `when` statement has an implicit `break` at the end. It is possible to fall through a case and continue comparing, but since falling through is less common, it is explicitly specified with a `continue`:

```given \$bugblatter {
when Beast::Trall { close_eyes(  ); continue; }
when 'ravenous'   { toss('steak'); continue; }
when 'attacking'  { hurl(\$spear, \$bugblatter); continue; }
when 'retreating' { toss('towel'); }
}```

The `default` case executes its block when all other cases fail:

```given \$bugblatter {
when Beast::Trall { close_eyes(  ); }
when 'ravenous'   { toss('steak'); }
default { run('away'); }
}```

Any code within a `given` will execute, but a successful `when` skips all remaining code within the `given`, not just the `when` statements. This means the `default` case isn’t really necessary, because any code after the final `when` just acts like a `default`. But an explicit `default` case makes the intention of the code clearer in the pure switch. There’s more than one way to do it (TMTOWTDI).

```given \$bugblatter {
print "Slowly I turn...";
when Beast::Trall { close_eyes(  ); }
print "Step by step...";
when 'ravenous'   { toss('steak'); }
print "Inch by inch...";
}```

The `when` statement can also appear outside a `given`. When they do, they simply smart match against `\$_`. `when` statements also have a statement modifier form. It doesn’t have an implicit `break`:

`print "Zaphod" when 'two heads';`

Iteration

Iteration executes one set of actions multiple times. Perl 6’s loop constructs are `while`, `until`, `loop`, and `for`.

The while loop

The `while` loop iterates as long as a condition is true. The condition may be complex, but the result is always a single boolean value because `while` imposes boolean context on its condition:

```while \$improbability > 1 {
print "\$improbability to 1 against and falling.";
\$improbability = drive_status('power_down');
}```

`until` is like `while` but continues looping as long as the condition is false.

The simple loop

In its simplest form, the `loop` construct is infinite. It will iterate until a statement within the loop explicitly terminates it:

```loop {
print "One more of that Ol' Janx.";
last if enough(  );
}```

`loop` is also the counter iterator. Like `while`, it tests a condition before executing its block each time, but it has added expression slots for initialization and execution between iterations that make it ideal for counter loops:

```loop ( \$counter = 1; \$counter < 20; \$counter++ ) {
print "Try to count electric sheep...";
}```

The for loop

The `for` loop is the list iterator, so it imposes list context. It takes any list or array, or any expression that produces a list, and loops through the list’s elements one at a time. On each iteration, `for` aliases `\$_` to the current loop element.[15]

This means all the constructs that default to `\$_`, like `print` and `when`, can default to the loop variable:

```for @useful_things {
print;
print " You're one hoopy frood." when 'towel';
}```

The arrow operator, `->`, makes a named alias to the current element, in addition to the `\$_` alias. All aliases are lexically scoped to the block:

```for %people.keys -> \$name {
print; # prints \$_ (same as \$name)
print ":", %people{\$name}{'age'};
}```

The arrow operator also makes it possible to iterate over multiple loop elements at the same time:

```for %ages.kv -> \$name, \$age {
print \$name, " is now ", \$age;
}```

You can combine the arrow operator with the `zip` function or zip operator to loop over several lists, taking some specified number of elements from each on every iteration, as in the following code.

```# one from each array
for zip(@people,@places,@things) -> \$person, \$place, \$thing {
print "Are you a \$person, \$place, or \$thing?";
}

# two from each array
for zip(@animals, @things, by=>2)
-> \$animal1, \$animal2, \$thing1, \$thing2 {

print "The animals, they came, they came in by twosies, twosies: ";
print "\$animal1 and \$animal2";

print "Two things. And I call them, \$thing1 and \$thing2.";

}

# two from the first array and one from the second
for zip(@colors=>2, @textures=>1) -> \$color1, \$color2, \$texture {
\$mix = blend(\$color1, \$color2);
draw_circle(\$mix, \$texture);
}```

Breaking out of loops

The `next` and `last` keywords allow you to interrupt the control flow of a loop. `next` skips the remaining code in the loop and starts the next iteration. `last` skips the remaining code in the loop and terminates the loop:

```for @useful_things -> \$item {
next when 'towel';
last when 'bomb';
print "Are you sure you need your \$item?";
}```

Blocks

In Perl 6, every block is a closure, so you get consistent behavior throughout the language, whether the block is a control structure, an argument passed to a subroutine, an anonymous subref, or the definition of a named element such as a subroutine, method, or class. What is a closure? Closures are chunks of code that are tied to the lexical scope in which they’re defined. When they’re stored and later executed at some point far removed from their definition, they execute using the variables in their original scope, even if those variables are no longer accessible any other way. It’s almost as if they package up their lexical scope to make it portable.

The fact that all blocks are closures has some implications. Every block can have arguments passed to it. This is how `for` creates a `\$_` alias for the iterator variable. Every block defines a lexical scope. Every block has the potential to be stored and executed later. Whether a block is stored or executed immediately depends on the structure that uses it. The control structures we’ve discussed so far all execute their blocks where they’re defined. A bare block executes immediately when it’s alone, but is stored when it’s in an assignment context or passed as a parameter:

```# executed immediately
{
print "Zaphod";
}

# stored
\$closure = {
print "Trillian";
}```

my, our, temp, and let

`my` and `our` are different ways of declaring variables. `my` declares a variable in the current lexical scratchpad, while `our` declares a lexical alias to a variable in the package symbol table.

```my \$lexical_var;
our \$package_var;```

`temp` and `let` are not declarations, they are runtime commands to store off the current value of a variable so it can be restored later. `temp` variables always restore their previous value on exiting the lexical scope of the `temp`, while `let` variables keep the temporary value, unless they are explicitly told to restore it:

```temp \$throwaway;
let \$hypothetical;```

Property blocks

Every block may have a series of control flow handlers attached to it. These are called "property blocks” because they are themselves blocks (i.e., closures), attached as properties on the block. Property blocks are defined within their enclosing block by an uppercase keyword followed by a block (they’re also sometimes called NAMED blocks):

```NEXT {
print "Coming around again."
}```

Property blocks aren’t executed in sequential order with the other code in the enclosing block—they are stored at compile time and executed at the appropriate point in the control flow. `NEXT` executes between each iteration of a loop, `LAST` executes at the end of the final iteration (or simply at the end of an ordinary block). `PRE` and `POST` are intended for assertion checking and cannot have any side effects. `PRE` executes before everything else in the block, and `POST` executes after everything else in the loop. `CATCH`, `KEEP`, and `UNDO` are related to exception handling. `KEEP` and `UNDO` are variants of `LAST` and execute after `CATCH`. `KEEP` executes when the block exits with no exceptions, or when all exceptions have been trapped and handled; `UNDO` executes when the block exits with untrapped exceptions.

This example prints out its loop variable in the body of the block:

```for 1..4 {
NEXT { print " potato, "; }
LAST { print "." }
print;

}```

Between each iteration, the `NEXT` block executes, printing “potato”. At the end of the final iteration, the `LAST` block prints a period. So the final result is “1 potato, 2 potato, 3 potato, 4”.

Property blocks are lexically scoped within their enclosing block, so they have access to lexical variables defined there.

```for 5..7 -> \$count {
my \$potato = " potato, ";
NEXT {
print \$count, \$potato;
}
LAST {
print \$count, \$potato, "more.";
}
}```

Exceptions

There are two types of exceptions: error exceptions and control flow exceptions. All exceptions are stored in the error object `\$!`. Exceptions are classes that inherit from the `Exception` class.

Error exceptions are thrown by `throw`, `die`, and `fail` (under `use fatal`). Any block can be an error exception handler. All it needs is a `CATCH` block. `CATCH` blocks always topicalize `\$!`, so the simplest way to test for a particular exception is to compare it to a class name using a `when` statement.[16]

```CATCH {
when Err::Danger { warn "fly away home"; }
}```

The `\$!` object will also stringify to its text message if you match it against a pattern.

```CATCH {
when /:w I'm sorry Dave/ { warn "HAL is in the house."; }
}```

If the `CATCH` block is exited by an explicit `break` statement, or by an implicit `break` in a `when` or `default` case, it marks the exception as clean. Otherwise, it rethrows the exception to be caught by some outer block.

Once an exception is thrown, execution skips straight to the `CATCH` block and the remaining code in the block is skipped. If the block has `POST` , `KEEP`, or `UNDO` property blocks, they will execute after the `CATCH` block.

Control flow exceptions handle alterations in the flow of control that aren’t errors. When you call `next` to skip the remaining code in the loop and go on to the next iteration, you’re actually throwing a control exception. These exceptions are caught by the relevant control structure: `next` and `last` exceptions are caught by loops, a `return` exception is caught by a subroutine or method, etc.

[14] `\$_` is always the current topic (think “topic of conversation”), so the process of aliasing a variable to `\$_` is known as “topicalization.”

[15] Topicalization again.

[16] See the earlier section Section 4.2.11 for a complete set of comparison relations.

Get Perl 6 Essentials now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.