- publishing free software manuals
Perl Language Reference Manual
by Larry Wall and others
Paperback (6"x9"), 724 pages
ISBN 9781906966027
RRP £29.95 ($39.95)

Sales of this book support The Perl Foundation! Get a printed copy>>>

4.5 Statement Modifiers

Any simple statement may optionally be followed by a SINGLE modifier, just before the terminating semicolon (or block ending). The possible modifiers are:

unless EXPR
while EXPR
until EXPR
when EXPR
for LIST
foreach LIST

The EXPR following the modifier is referred to as the "condition". Its truth or falsehood determines how the modifier will behave.

if executes the statement once if and only if the condition is true. unless is the opposite, it executes the statement unless the condition is true (i.e., if the condition is false).

print "Basset hounds got long ears" if length $ear >= 10;
go_outside() and play() unless $is_raining;

when executes the statement when $_ smart matches EXPR, and then either breaks out if it's enclosed in a given scope or skips to the next element when it lies directly inside a for loop. See also 4.11.

given ($something) {
    $abc    = 1 when /^abc/;
    $just_a = 1 when /^a/;
    $other  = 1;
for (@names) {
    admin($_)   when [ qw/Alice Bob/ ];
    regular($_) when [ qw/Chris David Ellen/ ];

The foreach modifier is an iterator: it executes the statement once for each item in the LIST (with $_ aliased to each item in turn).

print "Hello $_!\n" foreach qw(world Dolly nurse);

while repeats the statement while the condition is true. until does the opposite, it repeats the statement until the condition is true (or while the condition is false):

# Both of these count from 0 to 10.
print $i++ while $i <= 10;
print $j++ until $j >  10;

The while and until modifiers have the usual "while loop" semantics (conditional evaluated first), except when applied to a do-BLOCK (or to the deprecated do-SUBROUTINE statement), in which case the block executes once before the conditional is evaluated. This is so that you can write loops like:

do {
    $line = <STDIN>;
} until $line  eq ".\n";

See . Note also that the loop control statements described later will NOT work in this construct, because modifiers don't take loop labels. Sorry. You can always put another block inside of it (for next) or around it (for last) to do that sort of thing. For next, just double the braces:

do {{
    next if $x == $y;
    # do something here
}} until $x++ > $z;

For last, you have to be more elaborate:

LOOP: { 
        do {
            last if $x = $y**2;
            # do something here
        } while $x++ <= $z;

NOTE: The behaviour of a my statement modified with a statement modifier conditional or loop construct (e.g. my $x if ...) is undefined. The value of the my variable may be undef, any previously assigned value, or possibly anything else. Don't rely on it. Future versions of perl might do something different from the version of perl you try it out on. Here be dragons.

ISBN 9781906966027Perl Language Reference ManualSee the print edition