diff options
author | Zefram <zefram@fysh.org> | 2017-12-17 11:02:23 +0000 |
---|---|---|
committer | Zefram <zefram@fysh.org> | 2017-12-17 11:02:23 +0000 |
commit | da4e040f42421764ef069371d77c008e6b801f45 (patch) | |
tree | dad219b9c5a660c14705b6544fab2b3572bc2bd9 /pod/perlsyn.pod | |
parent | b2cd5cb1d8b3c8a7a7f033784d5134d2fbd8cad8 (diff) | |
parent | d6374f3d794e2a640258023e92e8d922409215ec (diff) | |
download | perl-da4e040f42421764ef069371d77c008e6b801f45.tar.gz |
merge branch zefram/dumb_match
Diffstat (limited to 'pod/perlsyn.pod')
-rw-r--r-- | pod/perlsyn.pod | 529 |
1 files changed, 115 insertions, 414 deletions
diff --git a/pod/perlsyn.pod b/pod/perlsyn.pod index f5a2f2a92a..f7ef20ff7f 100644 --- a/pod/perlsyn.pod +++ b/pod/perlsyn.pod @@ -118,7 +118,7 @@ as the last item in a statement. =head2 Statement Modifiers X<statement modifier> X<modifier> X<if> X<unless> X<while> -X<until> X<when> X<foreach> X<for> +X<until> X<whereis> X<whereso> 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 @@ -130,7 +130,8 @@ modifiers are: until EXPR for LIST foreach LIST - when EXPR + whereis EXPR + whereso EXPR The C<EXPR> following the modifier is referred to as the "condition". Its truth or falsehood determines how the modifier will behave. @@ -211,18 +212,15 @@ it. Future versions of perl might do something different from the version of perl you try it out on. Here be dragons. X<my> -The C<when> modifier is an experimental feature that first appeared in Perl -5.14. To use it, you should include a C<use v5.14> declaration. -(Technically, it requires only the C<switch> feature, but that aspect of it -was not available before 5.14.) Operative only from within a C<foreach> -loop or a C<given> block, it executes the statement only if the smartmatch -C<< $_ ~~ I<EXPR> >> is true. If the statement executes, it is followed by -a C<next> from inside a C<foreach> and C<break> from inside a C<given>. - -Under the current implementation, the C<foreach> loop can be -anywhere within the C<when> modifier's dynamic scope, but must be -within the C<given> block's lexical scope. This restriction may -be relaxed in a future release. See L</"Switch Statements"> below. +The C<whereis> and C<whereso> modifiers are an experimental feature +that first appeared with this spelling in Perl 5.28. To use them, you +should include a C<use feature 'switch'> declaration, or a declaration +that implies it. They behave like the full C<whereis> or C<whereso> +statement with block, described in L</"Switch Statements"> below. +They executes the statement only if the I<EXPR> is true for C<whereso>, +or C<$_> smartmatches the I<EXPR> for C<whereis>. If the statement +executes, control then implicitly jumps to the end of the dynamically +enclosing loop (usually a C<given> block). =head2 Compound Statements X<statement, compound> X<block> X<bracket, curly> X<curly bracket> X<brace> @@ -258,6 +256,9 @@ The following compound statements may be used to control flow: given (EXPR) BLOCK + whereis (EXPR) BLOCK + whereso (EXPR) BLOCK + LABEL while (EXPR) BLOCK LABEL while (EXPR) BLOCK continue BLOCK @@ -277,8 +278,9 @@ The following compound statements may be used to control flow: PHASE BLOCK -The experimental C<given> statement is I<not automatically enabled>; see -L</"Switch Statements"> below for how to do so, and the attendant caveats. +The experimental C<given>, C<whereis>, and C<whereso> statements are I<not +automatically enabled>; see L</"Switch Statements"> below for how to do +so, and the attendant caveats. Unlike in C and Pascal, in Perl these are all defined in terms of BLOCKs, not statements. This means that the curly brackets are I<required>--no @@ -598,8 +600,8 @@ The BLOCK construct can be used to emulate case structures. $nothing = 1; } -You'll also find that C<foreach> loop used to create a topicalizer -and a switch: +You'll also find the C<foreach> loop used to establish a topic for +a switch: SWITCH: for ($var) { @@ -611,96 +613,126 @@ and a switch: Such constructs are quite frequently used, both because older versions of Perl had no official C<switch> statement, and also because the new version -described immediately below remains experimental and can sometimes be confusing. +described immediately below remains experimental. =head2 Switch Statements -X<switch> X<case> X<given> X<when> X<default> +X<switch> X<case> X<given> X<whereis> X<whereso> -Starting from Perl 5.10.1 (well, 5.10.0, but it didn't work -right), you can say +C<given>, C<whereso>, and related keywords make up an experimental feature +that first appeared in Perl 5.10, but behaved quite differently from +its present form prior to Perl 5.28. To use it, you should declare use feature "switch"; -to enable an experimental switch feature. This is loosely based on an -old version of a Perl 6 proposal, but it no longer resembles the Perl 6 -construct. You also get the switch feature whenever you declare that your +You also get the switch feature whenever you declare that your code prefers to run under a version of Perl that is 5.10 or later. For example: use v5.14; -Under the "switch" feature, Perl gains the experimental keywords -C<given>, C<when>, C<default>, C<continue>, and C<break>. -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 -- though C<continue> is not -- so the code -in the previous section could be rewritten as +Under the "switch" feature, Perl gains the experimental keywords C<given>, +C<whereis>, and C<whereso>. 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 "switch" feature is considered highly experimental; it is subject +to change with little notice. Uses of the C<given>, C<whereis>, and +C<whereso> keywords will by default warn about their experimental status. +These warnings are in the same category as warnings about the C<~~> +(smartmatch) operator being experimental. + +The keywords C<given> and C<whereis> or C<whereso> +are analogous to C<switch> and C<case> +in C. They're meant to be used together, but can actually be used +independently and mixed with other kinds of compound statement. + +C<given> evaluates its argument in scalar context, and executes its block +with the C<$_> variable locally aliased to the result of evaluating the +argument expression. It is much like a C<foreach> loop that always has +exactly one item to iterate over. +A C<given> construct even counts as a one-iteration loop for the purposes +of loop control, so the C<redo> operator can be used to restart its block, +and C<next> or C<last> can be used to exit the block early. + +C<whereso> evaluates its argument as a truth value. If the argument +was false then it does not execute its block, and proceeds to the +following statement. If the argument was true, it executes the block, +then implicitly performs a C<next>, jumping to the end of the closest +dynamically enclosing C<given> block or other kind of loop. + +C<whereis> evaluates its argument and uses it as a smartmatch object, +checking whether C<$_> matches it. If C<$_> did not match then it does +not execute its block, and proceeds to the following statement. If C<$_> +did match, it executes the block, then implicitly performs a C<next>, +jumping to the end of the closest dynamically enclosing C<given> block +or other kind of loop. This is exactly like C<whereso>, except for the +implicit use of smartmatch. + +Putting this together, the code in the previous section could be +rewritten as use v5.10.1; - for ($var) { - when (/^abc/) { $abc = 1 } - when (/^def/) { $def = 1 } - when (/^xyz/) { $xyz = 1 } - default { $nothing = 1 } + given ($var) { + whereso (/^abc/) { $abc = 1 } + whereso (/^def/) { $def = 1 } + whereso (/^xyz/) { $xyz = 1 } + $nothing = 1; } -The C<foreach> is the non-experimental way to set a topicalizer. -If you wish to use the highly experimental C<given>, that could be -written like this: +Or if you prefer the modifier form of C<whereso>, it can be written with +less punctuation as - use v5.10.1; + use v5.14; given ($var) { - when (/^abc/) { $abc = 1 } - when (/^def/) { $def = 1 } - when (/^xyz/) { $xyz = 1 } - default { $nothing = 1 } + $abc = 1 whereso /^abc/; + $def = 1 whereso /^def/; + $xyz = 1 whereso /^xyz/; + $nothing = 1; } -As of 5.14, that can also be written this way: +You can use the C<continue> keyword to exit a C<whereis> or C<whereso> +block, proceeding to the following statement. This is most commonly +done last thing inside the block, to override the implicit C<next>. +For example - use v5.14; - for ($var) { - $abc = 1 when /^abc/; - $def = 1 when /^def/; - $xyz = 1 when /^xyz/; - default { $nothing = 1 } + given($foo) { + whereso (/x/) { say '$foo contains an x'; continue } + whereso (/y/) { say '$foo contains a y' } + say '$foo does not contain a y'; } -Or if you don't care to play it safe, like this: +When a C<given> statement is executed in a position where it will provide +a value, for example when it's the last statement of a subroutine and +so providing the subroutine's return value, it evaluates to: - use v5.14; - given ($var) { - $abc = 1 when /^abc/; - $def = 1 when /^def/; - $xyz = 1 when /^xyz/; - default { $nothing = 1 } - } +=over 4 + +=item * + +An empty list as soon as an explicit C<next> or C<last> is encountered. -The arguments to C<given> and C<when> are in scalar context, -and C<given> assigns the C<$_> variable its topic value. - -Exactly what the I<EXPR> argument to C<when> does is hard to describe -precisely, but in general, it tries to guess what you want done. Sometimes -it is interpreted as C<< $_ ~~ I<EXPR> >>, and sometimes it is not. It -also behaves differently when lexically enclosed by a C<given> block than -it does when dynamically enclosed by a C<foreach> loop. The rules are far -too difficult to understand to be described here. See L</"Experimental Details -on given and when"> later on. - -Due to an unfortunate bug in how C<given> was implemented between Perl 5.10 -and 5.16, under those implementations the version of C<$_> governed by -C<given> is merely a lexically scoped copy of the original, not a -dynamically scoped alias to the original, as it would be if it were a -C<foreach> or under both the original and the current Perl 6 language -specification. This bug was fixed in Perl 5.18 (and lexicalized C<$_> itself -was removed in Perl 5.24). - -If your code still needs to run on older versions, -stick to C<foreach> for your topicalizer and -you will be less unhappy. +=item * + +The value of the last evaluated expression of the successful +C<whereis> or C<whereso> clause, if there happens to be 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<whereis>/C<whereso> statements always +evaluate to an empty list. + +On versions of Perl preceding Perl 5.28, C<given> and the related keywords +behave quite differently from their present behaviour. If your code needs +to run on older versions, avoid C<given>, C<whereis>, and C<whereso>. =head2 Goto X<goto> @@ -911,335 +943,4 @@ shell: __END__ foo at goop line 345. -=head2 Experimental Details on given and when - -As previously mentioned, the "switch" feature is considered highly -experimental; it is subject to change with little notice. In particular, -C<when> has tricky behaviours that are expected to change to become less -tricky in the future. Do not rely upon its current (mis)implementation. -Before Perl 5.18, C<given> also had tricky behaviours that you should still -beware of if your code must run on older versions of Perl. - -Here is a longer example of C<given>: - - 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 'a complicated check for $foo is true'; - } - default { - die q(I don't know what to do with $foo); - } - } - -Before Perl 5.18, C<given(EXPR)> assigned the value of I<EXPR> to -merely a lexically scoped I<B<copy>> (!) of C<$_>, not a dynamically -scoped alias the way C<foreach> does. That made it similar to - - do { my $_ = EXPR; ... } - -except that the block was automatically broken out of by a successful -C<when> or an explicit C<break>. Because it was only a copy, and because -it was only lexically scoped, not dynamically scoped, you could not do the -things with it that you are used to in a C<foreach> loop. In particular, -it did not work for arbitrary function calls if those functions might try -to access $_. Best stick to C<foreach> for that. - -Most of the power comes from the implicit smartmatching that can -sometimes apply. Most of the time, C<when(EXPR)> is treated as an -implicit smartmatch of C<$_>, that is, C<$_ ~~ EXPR>. (See -L<perlop/"Smartmatch Operator"> for more information on smartmatching.) -But when I<EXPR> is one of the 10 exceptional cases (or things like them) -listed below, it is used directly as a boolean. - -=over 4 - -=item Z<>1. - -A user-defined subroutine call or a method invocation. - -=item Z<>2. - -A regular expression match in the form of C</REGEX/>, C<$foo =~ /REGEX/>, -or C<$foo =~ EXPR>. Also, a negated regular expression match in -the form C<!/REGEX/>, C<$foo !~ /REGEX/>, or C<$foo !~ EXPR>. - -=item Z<>3. - -A smart match that uses an explicit C<~~> operator, such as C<EXPR ~~ EXPR>. - -B<NOTE:> You will often have to use C<$c ~~ $_> because the default case -uses C<$_ ~~ $c> , which is frequentlythe opposite of what you want. - -=item Z<>4. - -A boolean comparison operator such as C<$_ E<lt> 10> or C<$x eq "abc">. The -relational operators that this applies to are the six numeric comparisons -(C<< < >>, C<< > >>, C<< <= >>, C<< >= >>, C<< == >>, and C<< != >>), and -the six string comparisons (C<lt>, C<gt>, C<le>, C<ge>, C<eq>, and C<ne>). - -=item Z<>5. - -At least the three builtin functions C<defined(...)>, C<exists(...)>, and -C<eof(...)>. We might someday add more of these later if we think of them. - -=item Z<>6. - -A negated expression, whether C<!(EXPR)> or C<not(EXPR)>, or a logical -exclusive-or, C<(EXPR1) xor (EXPR2)>. The bitwise versions (C<~> and C<^>) -are not included. - -=item Z<>7. - -A filetest operator, with exactly 4 exceptions: C<-s>, C<-M>, C<-A>, and -C<-C>, as these return numerical values, not boolean ones. The C<-z> -filetest operator is not included in the exception list. - -=item Z<>8. - -The C<..> and C<...> flip-flop operators. Note that the C<...> flip-flop -operator is completely different from the C<...> elliptical statement -just described. - -=back - -In those 8 cases above, the value of EXPR is used directly as a boolean, so -no smartmatching is done. You may think of C<when> as a smartsmartmatch. - -Furthermore, Perl inspects the operands of logical operators to -decide whether to use smartmatching for each one by applying the -above test to the operands: - -=over 4 - -=item Z<>9. - -If EXPR is C<EXPR1 && EXPR2> or C<EXPR1 and EXPR2>, the test is applied -I<recursively> to both EXPR1 and EXPR2. -Only if I<both> operands also pass the -test, I<recursively>, will the expression be treated as boolean. Otherwise, -smartmatching is used. - -=item Z<>10. - -If EXPR is C<EXPR1 || EXPR2>, C<EXPR1 // EXPR2>, or C<EXPR1 or EXPR2>, the -test is applied I<recursively> to EXPR1 only (which might itself be a -higher-precedence AND operator, for example, and thus subject to the -previous rule), not to EXPR2. If EXPR1 is to use smartmatching, then EXPR2 -also does so, no matter what EXPR2 contains. But if EXPR2 does not get to -use smartmatching, then the second argument will not be either. This is -quite different from the C<&&> case just described, so be careful. - -=back - -These rules are complicated, but the goal is for them to do what you want -(even if you don't quite understand why they are doing it). 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 C<$_> will be treated -as boolean. - -Also: - - when ([qw(foo bar)] && /baz/) { ... } - -will use smartmatching because only I<one> of the operands is a boolean: -the other uses smartmatching, 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. Not a good idea. - -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 smartmatch -on C<"foo">). For an alternation like -this, an array ref will work, because this will instigate smartmatching: - - 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<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. - -=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 immediate C<when> or C<default>: - - 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 Return value - -When a C<given> statement is also a valid expression (for example, -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 happens to be 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. -For example, here's one way to count how many times a particular -string occurs in an array: - - use v5.10.1; - my $count = 0; - for (@array) { - when ("foo") { ++$count } - } - print "\@array contains $count copies of 'foo'\n"; - -Or in a more recent version: - - use v5.14; - my $count = 0; - for (@array) { - ++$count when "foo"; - } - print "\@array contains $count copies of 'foo'\n"; - -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 -interested in only the first match alone. - -This doesn't work if you explicitly specify a loop variable, as -in C<for $item (@array)>. You have to use the default variable C<$_>. - -=head3 Differences from Perl 6 - -The Perl 5 smartmatch and C<given>/C<when> constructs are not compatible -with their Perl 6 analogues. The most visible difference and least -important difference is that, in Perl 5, parentheses are required around -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 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. - -However, their are many, many other differences. For example, -this works in Perl 5: - - use v5.12; - my @primary = ("red", "blue", "green"); - - if (@primary ~~ "red") { - say "primary smartmatches red"; - } - - if ("red" ~~ @primary) { - say "red smartmatches primary"; - } - - say "that's all, folks!"; - -But it doesn't work at all in Perl 6. Instead, you should -use the (parallelizable) C<any> operator: - - if any(@primary) eq "red" { - say "primary smartmatches red"; - } - - if "red" eq any(@primary) { - say "red smartmatches primary"; - } - -The table of smartmatches in L<perlop/"Smartmatch Operator"> is not -identical to that proposed by the Perl 6 specification, mainly due to -differences between Perl 6's and Perl 5's data models, but also because -the Perl 6 spec has changed since Perl 5 rushed into early adoption. - -In Perl 6, C<when()> will always do an implicit smartmatch with its -argument, while in Perl 5 it is convenient (albeit potentially confusing) to -suppress this implicit smartmatch in various rather loosely-defined -situations, as roughly outlined above. (The difference is largely because -Perl 5 does not have, even internally, a boolean type.) - =cut |