=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).
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 'a complicated check for $foo is true';
}
-
default {
die q(I don't know what to do with $foo);
}
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
In those cases the value of EXPR is used directly as a boolean.
=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.)
$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 slice existence 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 slice existence 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:
+ 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
+ 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
The "matching code" doesn't represent the I<real> matching code,
of course: it's just there to explain the intended meaning. Unlike
the C<~~> operator. This trumps the usual smart match semantics.
See L<overload>.
+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).
+
=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