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
}
-Most of its power comes from the implicit smart matching:
+ 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);
+ }
+ }
+
+C<given(EXPR)> will assign the value of EXPR to C<$_>
+within the lexical scope of the block, so it's similar to
+
+ 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) ...
+ 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)>
=item o
-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
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 contains neither an x nor 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 value slice truth grep $_, @$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)
+ * - 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>.
=head2 Goto
X<goto>