the sense of the test is reversed.
The C<while> statement executes the block as long as the expression is
-true (does not evaluate to the null string C<""> or C<0> or C<"0">).
+L<true|/"Truth and Falsehood">.
The C<until> statement executes the block as long as the expression is
false.
The LABEL is optional, and if present, consists of an identifier followed
This construct is very flexible and powerful. For example:
- given() {
- xxxx
+ use feature ":5.10";
+ given($foo) {
+ 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';
+ }
+
+ default {
+ die q(I don't know what to do with $foo);
+ }
}
-Most of its power comes from the implicit smart matching:
+C<given(EXPR)> will assign the value of EXPR to C<$_>
+within the lexical scope of the block, so it's similar to
- when($foo) ...
+ do { my $_ = EXPR; ... }
+
+except that the block is automatically broken out of by a
+successful C<when> or an explicit C<break>.
+
+Most of the power comes from implicit smart matching:
+
+ when($foo)
is exactly equivalent to
- when($_ ~~ $foo) ...
+ when($_ ~~ $foo)
-(though you need to enable the "~~" feature before you
-can use the C<~~> operator directly). In fact C<when(EXPR)>
-is treated as an implicit smart match most of the time. The
-exceptions are that when EXPR is:
+In fact C<when(EXPR)> is treated as an implicit smart match most of the
+time. The exceptions are that when EXPR is:
=over 4
-=item o
+=item *
a subroutine or method call
-=item o
+=item *
a regular expression match, i.e. C</REGEX/> or C<$foo =~ /REGEX/>,
or a negated regular expression match C<$foo !~ /REGEX/>.
-=item o
+=item *
-a comparison (such as C<$_ E<lt> 10> or C<$x gt "abc">
+a comparison such as C<$_ E<lt> 10> or C<$x eq "abc">
+(or of course C<$_ ~~ $c>)
-=item o
+=item *
C<defined(...)>, C<exists(...)>, or C<eof(...)>
-=item o
+=item *
A negated expression C<!(...)> or C<not (...)>, or a logical
exclusive-or C<(...) xor (...)>.
These rules look complicated, but usually they will do what
you want. For example you could write:
- when (/^\d$/ && $_ < 75) { ... }
+ when (/^\d+$/ && $_ < 75) { ... }
+
+Another useful shortcut is that, if you use a literal array
+or hash as the argument to C<when>, 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
+C<given> block. Every C<when> block is implicitly ended with
+a C<break>.
+
=head3 Fall-through
You can use the C<continue> keyword to fall through from one
case to the next:
given($foo) {
- when (/x/) { print "\$foo contains an 'x'\n"; continue }
- when (/y/) { print "\$foo contains a 'y'\n" }
- default { print "\$foo contains neither an 'x' nor a 'y' }
+ when (/x/) { say '$foo contains an x'; continue }
+ when (/y/) { say '$foo contains a y' }
+ default { say '$foo does not contain a y' }
}
=head3 Switching in a loop
=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.
+
+
+ $a $b Type of Match Implied Matching Code
+ ====== ===== ===================== =============
+ (overloading trumps everything)
+
+ Code[+] Code[+] referential equality $a == $b
+ Any Code[+] scalar sub truth $b->($a)
+
+ Hash Hash hash keys identical [sort keys %$a]~~[sort keys %$b]
+ Hash Array hash slice existence grep {exists $a->{$_}} @$b
+ Hash Regex hash key grep grep /$b/, keys %$a
+ Hash Any hash entry existence exists $a->{$b}
+
+ 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
+
+ Any undef undefined !defined $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
+
+ 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.
=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 trumps the usual smart match semantics.
+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
+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
+would parse the expression
+
+ given $foo {
+ ...
+ }
+
+as though the argument to C<given> were an element of the hash
+C<%foo>, interpreting the braces as hash-element syntax.
+
+The table of smart matches is not identical to that proposed by the
+Perl 6 specification, mainly due to the differences between Perl 6's
+and Perl 5's data models.
+
+In Perl 6, C<when()> will always do an implicit smart match
+with its argument, whilst it is convenient in Perl 5 to
+suppress this implicit smart match in certain situations,
+as documented above. (The difference is largely because Perl 5
+does not, even internally, have a boolean type.)
=head2 Goto
X<goto>