=head2 Statement Modifiers
X<statement modifier> X<modifier> X<if> X<unless> X<while>
-X<until> X<foreach> X<for>
+X<until> X<when> X<foreach> X<for>
Any simple statement may optionally be followed by a I<SINGLE> modifier,
just before the terminating semicolon (or block ending). The possible
unless EXPR
while EXPR
until EXPR
+ when EXPR
+ for LIST
foreach LIST
The C<EXPR> following the modifier is referred to as the "condition".
print "Basset hounds got long ears" if length $ear >= 10;
go_outside() and play() unless $is_raining;
+C<when> executes the statement I<when> C<$_> smart matches C<EXPR>, and
+then either C<break>s out if it's enclosed in a C<given> scope or skips
+to the C<next> element when it lies directly inside a C<for> loop.
+See also L</"Switch statements">.
+
+ 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 C<foreach> modifier is an iterator: it executes the statement once
for each item in the LIST (with C<$_> aliased to each item in turn).
if (EXPR) BLOCK
if (EXPR) BLOCK else BLOCK
if (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK
+ unless (EXPR) BLOCK
+ unless (EXPR) BLOCK else BLOCK
+ unless (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK
LABEL while (EXPR) BLOCK
LABEL while (EXPR) BLOCK continue BLOCK
LABEL until (EXPR) BLOCK
LABEL until (EXPR) BLOCK continue BLOCK
LABEL for (EXPR; EXPR; EXPR) BLOCK
+ LABEL for VAR (LIST) BLOCK
+ LABEL for VAR (LIST) BLOCK continue BLOCK
+ LABEL foreach (EXPR; EXPR; EXPR) BLOCK
LABEL foreach VAR (LIST) BLOCK
LABEL foreach VAR (LIST) BLOCK continue BLOCK
LABEL BLOCK continue BLOCK
+ PHASE BLOCK
Note that, unlike C and Pascal, these are defined in terms of BLOCKs,
not statements. This means that the curly brackets are I<required>--no
The C<if> statement is straightforward. Because BLOCKs are always
bounded by curly brackets, there is never any ambiguity about which
C<if> an C<else> goes with. If you use C<unless> in place of C<if>,
-the sense of the test is reversed.
+the sense of the test is reversed. Like C<if>, C<unless> can be followed
+by C<else>. C<unless> can even be followed by one or more C<elsif>
+statements, though you may want to think twice before using that particular
+language construct, as everyone reading your code will have to think at least
+twice before they can understand what's going on.
The C<while> statement executes the block as long as the expression is
L<true|/"Truth and Falsehood">.
increment a loop variable, even when the loop has been continued via
the C<next> statement.
+When a block is preceding by a compilation phase keyword such as C<BEGIN>,
+C<END>, C<INIT>, C<CHECK>, or C<UNITCHECK>, then the block will run only
+during the corresponding phase of execution. See L<perlmod> for more details.
+
+Extension modules can also hook into the Perl parser to define new
+kinds of compound statement. These are introduced by a keyword which
+the extension recognizes, and the syntax following the keyword is
+defined entirely by the extension. If you are an implementor, see
+L<perlapi/PL_keyword_plugin> for the mechanism. If you are using such
+a module, see the module's documentation for details of the syntax that
+it defines.
+
=head2 Loop Control
X<loop control> X<loop, control> X<next> X<last> X<redo> X<continue>
Note that if there were a C<continue> block on the above code, it would
get executed only on lines discarded by the regex (since redo skips the
continue block). A continue block is often used to reset line counters
-or C<?pat?> one-time matches:
+or C<m?pat?> one-time matches:
# inspired by :1,$g/fred/s//WILMA/
while (<>) {
- ?(fred)? && s//WILMA $1 WILMA/;
- ?(barney)? && s//BETTY $1 BETTY/;
- ?(homer)? && s//MARGE $1 MARGE/;
+ m?(fred)? && s//WILMA $1 WILMA/;
+ m?(barney)? && s//BETTY $1 BETTY/;
+ m?(homer)? && s//MARGE $1 MARGE/;
} continue {
print "$ARGV $.: $_";
- close ARGV if eof(); # reset $.
- reset if eof(); # reset ?pat?
+ close ARGV if eof; # reset $.
+ reset if eof; # reset ?pat?
}
If the word C<while> is replaced by the word C<until>, the sense of the
implicitly local to the loop and regains its former value upon exiting
the loop. If the variable was previously declared with C<my>, it uses
that variable instead of the global one, but it's still localized to
-the loop. This implicit localisation occurs I<only> in a C<foreach>
+the loop. This implicit localization occurs I<only> in a C<foreach>
loop.
X<my> X<local>
of Perl had no official C<switch> statement.
=head2 Switch statements
+
X<switch> X<case> X<given> X<when> X<default>
Starting from Perl 5.10, you can say
use feature "switch";
which enables a switch feature that is closely based on the
-Perl 6 proposal.
+Perl 6 proposal. Starting from Perl 5.16, one can prefix the switch
+keywords with C<CORE::> to access the feature without a C<use feature>
+statement.
The keywords C<given> and C<when> are analogous
to C<switch> and C<case> in other languages, so the code
when (undef) {
say '$foo is undefined';
}
-
when ("foo") {
say '$foo is the string "foo"';
}
-
when ([1,3,5,7,9]) {
say '$foo is an odd digit';
continue; # Fall through
}
-
when ($_ < 100) {
say '$foo is numerically less than 100';
}
-
when (\&complicated_check) {
- say 'complicated_check($foo) is true';
+ say 'a complicated check for $foo is true';
}
-
default {
die q(I don't know what to do with $foo);
}
when($_ ~~ $foo)
-In fact C<when(EXPR)> is treated as an implicit smart match most of the
-time. The exceptions are that when EXPR is:
+Most of the time, C<when(EXPR)> is treated as an implicit smart match of
+C<$_>, i.e. C<$_ ~~ EXPR>. (See L</"Smart matching in detail"> for more
+information on smart matching.) But when EXPR is one of the below
+exceptional cases, it is used directly as a boolean:
=over 4
=item *
a regular expression match, i.e. C</REGEX/> or C<$foo =~ /REGEX/>,
-or a negated regular expression match C<$foo !~ /REGEX/>.
+or a negated regular expression match (C<!/REGEX/> or C<$foo !~ /REGEX/>).
=item *
=item *
-A negated expression C<!(...)> or C<not (...)>, or a logical
+a negated expression C<!(...)> or C<not (...)>, or a logical
exclusive-or C<(...) xor (...)>.
+=item *
+
+a filetest operator, with the exception of C<-s>, C<-M>, C<-A>, and C<-C>,
+that return numerical values, not boolean ones.
+
+=item *
+
+the C<..> and C<...> flip-flop operators.
+
=back
-then the value of EXPR is used directly as a boolean.
-Furthermore:
+In those cases the value of EXPR is used directly as a boolean.
+
+Furthermore, Perl inspects the operands of the binary boolean operators to
+decide whether to use smart matching for each one by applying the above test to
+the operands:
=over 4
-=item o
+=item *
If EXPR is C<... && ...> or C<... and ...>, the test
-is applied recursively to both arguments. If I<both>
-arguments pass the test, then the argument is treated
-as boolean.
+is applied recursively to both operands. If I<both>
+operands pass the test, then the expression is treated
+as boolean; otherwise, smart matching is used.
-=item o
+=item *
-If EXPR is C<... || ...> or C<... or ...>, the test
-is applied recursively to the first argument.
+If EXPR is C<... || ...>, C<... // ...> or C<... or ...>, the test
+is applied recursively to the first operand (which may be a
+higher-precedence AND operator, for example). If the first operand
+is to use smart matching, then both operands will do so; if it is
+not, then the second argument will not be either.
=back
These rules look complicated, but usually they will do what
-you want. For example you could write:
+you want. For example:
when (/^\d+$/ && $_ < 75) { ... }
+will be treated as a boolean match because the rules say both a regex match and
+an explicit test on $_ will be treated as boolean.
+
+Also:
+
+ when ([qw(foo bar)] && /baz/) { ... }
+
+will use smart matching because only I<one> of the operands is a boolean; the
+other uses smart matching, and that wins.
+
+Further:
+
+ when ([qw(foo bar)] || /^baz/) { ... }
+
+will use smart matching (only the first operand is considered), whereas
+
+ when (/^baz/ || [qw(foo bar)]) { ... }
+
+will test only the regex, which causes both operands to be treated as boolean.
+Watch out for this one, then, because an arrayref is always a true value, which
+makes it effectively redundant.
+
+Tautologous boolean operators are still going to be optimized away. Don't be
+tempted to write
+
+ when ('foo' or 'bar') { ... }
+
+This will optimize down to C<'foo'>, so C<'bar'> will never be considered (even
+though the rules say to use a smart match on C<'foo'>). For an alternation like
+this, an array ref will work, because this will instigate smart matching:
+
+ when ([qw(foo bar)] { ... }
+
+This is somewhat equivalent to the C-style switch statement's fallthrough
+functionality (not to be confused with I<Perl's> fallthrough functionality - see
+below), wherein the same block is used for several C<case> statements.
+
Another useful shortcut is that, if you use a literal array
-or hash as the argument to C<when>, it is turned into a
+or hash as the argument to C<given>, it is turned into a
reference. So C<given(@foo)> is the same as C<given(\@foo)>,
for example.
C<default> behaves exactly like C<when(1 == 1)>, which is
to say that it always matches.
-See L</"Smart matching in detail"> for more information
-on smart matching.
-
=head3 Breaking out
You can use the C<break> keyword to break out of the enclosing
default { say '$foo does not contain a y' }
}
+=head3 Return value
+
+When a C<given> statement is also a valid expression (e.g.
+when it's the last statement of a block), it evaluates to :
+
+=over 4
+
+=item *
+
+an empty list as soon as an explicit C<break> is encountered.
+
+=item *
+
+the value of the last evaluated expression of the successful
+C<when>/C<default> clause, if there's one.
+
+=item *
+
+the value of the last evaluated expression of the C<given> block if no
+condition is true.
+
+=back
+
+In both last cases, the last expression is evaluated in the context that
+was applied to the C<given> block.
+
+Note that, unlike C<if> and C<unless>, failed C<when> statements always
+evaluate to an empty list.
+
+ my $price = do { given ($item) {
+ when ([ 'pear', 'apple' ]) { 1 }
+ break when 'vote'; # My vote cannot be bought
+ 1e10 when /Mona Lisa/;
+ 'unknown';
+ } };
+
+Currently, C<given> blocks can't always be used as proper expressions. This
+may be addressed in a future version of perl.
+
=head3 Switching in a loop
Instead of using C<given()>, you can use a C<foreach()> loop.
}
print "\@array contains $count copies of 'foo'\n";
-On exit from the C<when> block, there is an implicit C<next>.
+At the end of all C<when> blocks, there is an implicit C<next>.
You can override that with an explicit C<last> if you're only
interested in the first match.
=head3 Smart matching in detail
-The behaviour of a smart match depends on what type of thing
-its arguments are. It is always commutative, i.e. C<$a ~~ $b>
-behaves the same as C<$b ~~ $a>. The behaviour is determined
-by the following table: the first row that applies, in either
-order, determines the match behaviour.
+The behaviour of a smart match depends on what type of thing its arguments
+are. The behaviour is determined by the following table: the first row
+that applies determines the match behaviour (which is thus mostly
+determined by the type of the right operand). Note that the smart match
+implicitly dereferences any non-blessed hash or array ref, so the "Hash"
+and "Array" entries apply in those cases. (For blessed references, the
+"Object" entries apply.)
+Note that the "Matching Code" column is not always an exact rendition. For
+example, the smart match operator short-circuits whenever possible, but
+C<grep> does not.
$a $b Type of Match Implied Matching Code
====== ===== ===================== =============
- (overloading trumps everything)
+ Any undef undefined !defined $a
- Code[+] Code[+] referential equality $a == $b
- Any Code[+] scalar sub truth $b->($a)
+ Any Object invokes ~~ overloading on $object, or dies
- Hash Hash hash keys identical [sort keys %$a]~~[sort keys %$b]
- Hash Array hash slice existence @$b == grep {exists $a->{$_}} @$b
- Hash Regex hash key grep grep /$b/, keys %$a
- Hash Any hash entry existence exists $a->{$b}
+ Hash CodeRef sub truth for each key[1] !grep { !$b->($_) } keys %$a
+ Array CodeRef sub truth for each elt[1] !grep { !$b->($_) } @$a
+ Any CodeRef scalar sub truth $b->($a)
- Array Array arrays are identical[*]
- Array Regex array grep grep /$b/, @$a
- Array Num array contains number grep $_ == $b, @$a
- Array Any array contains string grep $_ eq $b, @$a
+ Hash Hash hash keys identical (every key is found in both hashes)
+ Array Hash hash keys intersection grep { exists $b->{$_} } @$a
+ Regex Hash hash key grep grep /$a/, keys %$b
+ undef Hash always false (undef can't be a key)
+ Any Hash hash entry existence exists $b->{$a}
- Any undef undefined !defined $a
+ Hash Array hash keys intersection grep { exists $a->{$_} } @$b
+ Array Array arrays are comparable[2]
+ Regex Array array grep grep /$a/, @$b
+ undef Array array contains undef grep !defined, @$b
+ Any Array match against an array element[3]
+ grep $a ~~ $_, @$b
+
+ Hash Regex hash key grep grep /$b/, keys %$a
+ Array Regex array grep grep /$b/, @$a
Any Regex pattern match $a =~ /$b/
- Code() Code() results are equal $a->() eq $b->()
- Any Code() simple closure truth $b->() # ignoring $a
- Num numish[!] numeric equality $a == $b
- Any Str string equality $a eq $b
- Any Num numeric equality $a == $b
+ Object Any invokes ~~ overloading on $object, or falls back:
+ undef Any undefined !defined($b)
+ Any Num numeric equality $a == $b
+ Num numish[4] numeric equality $a == $b
Any Any string equality $a eq $b
-
- + - this must be a code reference whose prototype (if present) is not ""
- (subs with a "" prototype are dealt with by the 'Code()' entry lower down)
- * - that is, each element matches the element of same index in the other
- array. If a circular reference is found, we fall back to referential
- equality.
- ! - either a real number, or a string that looks like a number
-
-The "matching code" doesn't represent the I<real> matching code,
-of course: it's just there to explain the intended meaning. Unlike
-C<grep>, the smart match operator will short-circuit whenever it can.
+ 1 - empty hashes or arrays will match.
+ 2 - that is, each element smart-matches the element of same index in the
+ other array. [3]
+ 3 - If a circular reference is found, we fall back to referential equality.
+ 4 - either a real number, or a string that looks like a number
=head3 Custom matching via overloading
You can change the way that an object is matched by overloading
-the C<~~> operator. This trumps the usual smart match semantics.
+the C<~~> operator. This may alter the usual smart match semantics.
+
+It should be noted that C<~~> will refuse to work on objects that
+don't overload it (in order to avoid relying on the object's
+underlying structure).
+
+Note also that smart match's matching rules take precedence over
+overloading, so if C<$obj> has smart match overloading, then
+
+ $obj ~~ X
+
+will not automatically invoke the overload method with X as an argument;
+instead the table above is consulted as normal, and based in the type of X,
+overloading may or may not be invoked.
+
See L<overload>.
=head3 Differences from Perl 6
The Perl 5 smart match and C<given>/C<when> constructs are not
absolutely identical to their Perl 6 analogues. The most visible
difference is that, in Perl 5, parentheses are required around
-the argument to C<given()> and C<when()>. Parentheses in Perl 6
+the argument to C<given()> and C<when()> (except when this last
+one is used as a statement modifier). Parentheses in Perl 6
are always optional in a control construct such as C<if()>,
C<while()>, or C<when()>; they can't be made optional in Perl
5 without a great deal of potential confusion, because Perl 5
Perl can process line directives, much like the C preprocessor. Using
this, one can control Perl's idea of filenames and line numbers in
error or warning messages (especially for strings that are processed
-with C<eval()>). The syntax for this mechanism is the same as for most
-C preprocessors: it matches the regular expression
+with C<eval()>). The syntax for this mechanism is almost the same as for
+most C preprocessors: it matches the regular expression
# example: '# line 42 "new_filename.plx"'
/^\# \s*
line \s+ (\d+) \s*
- (?:\s("?)([^"]+)\2)? \s*
+ (?:\s("?)([^"]+)\g2)? \s*
$/x
with C<$1> being the line number for the next line, and C<$3> being
-the optional filename (specified with or without quotes).
+the optional filename (specified with or without quotes). Note that
+no whitespace may precede the C<< # >>, unlike modern C preprocessors.
There is a fairly obvious gotcha included with the line directive:
Debuggers and profilers will only show the last source line to appear
% perl
# line 200 "bzzzt"
- # the `#' on the previous line must be the first char on line
+ # the '#' on the previous line must be the first char on line
die 'foo';
__END__
foo at bzzzt line 201.