X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlsyn.pod;h=ec865103c55ae71e6c6556ec94b029d0564514f8;hb=9f2f055aa1e8c86d97b5ea42473ab1747f518f3a;hp=cc91e31521419a302d7ec4eccd43f09e3f027a0c;hpb=0d863452f5cac86322a90184dc68dbf446006ed7;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlsyn.pod b/pod/perlsyn.pod index cc91e31..ec86510 100644 --- a/pod/perlsyn.pod +++ b/pod/perlsyn.pod @@ -237,7 +237,7 @@ C an C goes with. If you use C in place of C, the sense of the test is reversed. The C 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. The C statement executes the block as long as the expression is false. The LABEL is optional, and if present, consists of an identifier followed @@ -331,7 +331,7 @@ they aren't loops. You can double the braces to make them such, though. }} This is caused by the fact that a block by itself acts as a loop that -executes once, see L<"Basic BLOCKs and Switch Statements">. +executes once, see L<"Basic BLOCKs">. The form C, available in Perl 4, is no longer available. Replace any occurrence of C by C. @@ -476,8 +476,7 @@ I true in C, C, or contrary to popular belief C blocks, which do I count as loops.) The C block is optional. -The BLOCK construct can be used to emulate case -structures. +The BLOCK construct can be used to emulate case structures. SWITCH: { if (/^abc/) { $abc = 1; last SWITCH; } @@ -489,13 +488,12 @@ structures. Such constructs are quite frequently used, because older versions of Perl had no official C statement. - =head2 Switch statements X X X X X -Starting from Perl 5.10, you can say +Starting from Perl 5.10, you can say - use feature "switch"; + use feature "switch"; which enables a switch feature that is closely based on the Perl 6 proposal. @@ -504,53 +502,83 @@ The keywords C and C are analogous to C and C in other languages, so the code above could be written as - given($_) { - when (/^abc/) { $abc = 1; } - when (/^def/) { $def = 1; } - when (/^xyz/) { $xyz = 1; } - default { $nothing = 1; } + given($_) { + when (/^abc/) { $abc = 1; } + when (/^def/) { $def = 1; } + when (/^xyz/) { $xyz = 1; } + default { $nothing = 1; } } 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 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 or an explicit C. + +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 -is treated as an implicit smart match most of the time. The -exceptions are that when EXPR is: +In fact C 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 or C<$foo =~ /REGEX/>, or a negated regular expression match C<$foo !~ /REGEX/>. -=item o +=item * -a comparison (such as C<$_ E 10> or C<$x gt "abc"> +a comparison such as C<$_ E 10> or C<$x eq "abc"> +(or of course C<$_ ~~ $c>) -=item o +=item * C, C, or C -=item o +=item * A negated expression C or C, or a logical exclusive-or C<(...) xor (...)>. @@ -579,7 +607,12 @@ is applied recursively to the first argument. 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, it is turned into a +reference. So C is the same as C, +for example. C behaves exactly like C, which is to say that it always matches. @@ -587,16 +620,22 @@ to say that it always matches. See L for more information on smart matching. +=head3 Breaking out + +You can use the C keyword to break out of the enclosing +C block. Every C block is implicitly ended with +a C. + =head3 Fall-through You can use the C 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' } - } + given($foo) { + 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 @@ -604,11 +643,11 @@ Instead of using C, you can use a C loop. For example, here's one way to count how many times a particular string occurs in an array: - my $count = 0; - for (@array) { - when ("foo") { ++$count } + my $count = 0; + for (@array) { + when ("foo") { ++$count } } - print "\@array contains $count copies of 'foo'\n"; + print "\@array contains $count copies of 'foo'\n"; On exit from the C block, there is an implicit C. You can override that with an explicit C if you're only @@ -620,12 +659,85 @@ variable C<$_>. (You can use C.) =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 @$b == 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 matching code, +of course: it's just there to explain the intended meaning. Unlike +C, 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. + +=head3 Differences from Perl 6 + +The Perl 5 smart match and C/C 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 and C. Parentheses in Perl 6 +are always optional in a control construct such as C, +C, or C; 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 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 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