summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlperl/lib/pods/perlsyn.pod
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlperl/lib/pods/perlsyn.pod')
-rw-r--r--Master/tlpkg/tlperl/lib/pods/perlsyn.pod118
1 files changed, 100 insertions, 18 deletions
diff --git a/Master/tlpkg/tlperl/lib/pods/perlsyn.pod b/Master/tlpkg/tlperl/lib/pods/perlsyn.pod
index 6359df4e141..603dd15ae83 100644
--- a/Master/tlpkg/tlperl/lib/pods/perlsyn.pod
+++ b/Master/tlpkg/tlperl/lib/pods/perlsyn.pod
@@ -281,7 +281,7 @@ the C<next> statement.
Extension modules can also hook into the Perl parser to define new
kinds of compound statement. These are introduced by a keyword which
-the extension recognises, and the syntax following the keyword is
+the extension recognizes, and the syntax following the keyword is
defined entirely by the extension. If you are an implementor, see
L<perlapi/PL_keyword_plugin> for the mechanism. If you are using such
a module, see the module's documentation for details of the syntax that
@@ -337,17 +337,17 @@ which is Perl short-hand for the more explicitly written version:
Note that if there were a C<continue> block on the above code, it would
get executed only on lines discarded by the regex (since redo skips the
continue block). A continue block is often used to reset line counters
-or C<?pat?> one-time matches:
+or C<m?pat?> one-time matches:
# inspired by :1,$g/fred/s//WILMA/
while (<>) {
- ?(fred)? && s//WILMA $1 WILMA/;
- ?(barney)? && s//BETTY $1 BETTY/;
- ?(homer)? && s//MARGE $1 MARGE/;
+ m?(fred)? && s//WILMA $1 WILMA/;
+ m?(barney)? && s//BETTY $1 BETTY/;
+ m?(homer)? && s//MARGE $1 MARGE/;
} continue {
print "$ARGV $.: $_";
- close ARGV if eof(); # reset $.
- reset if eof(); # reset ?pat?
+ close ARGV if eof; # reset $.
+ reset if eof; # reset ?pat?
}
If the word C<while> is replaced by the word C<until>, the sense of the
@@ -426,7 +426,7 @@ is therefore visible only within the loop. Otherwise, the variable is
implicitly local to the loop and regains its former value upon exiting
the loop. If the variable was previously declared with C<my>, it uses
that variable instead of the global one, but it's still localized to
-the loop. This implicit localisation occurs I<only> in a C<foreach>
+the loop. This implicit localization occurs I<only> in a C<foreach>
loop.
X<my> X<local>
@@ -626,29 +626,71 @@ the C<..> and C<...> flip-flop operators.
In those cases the value of EXPR is used directly as a boolean.
-Furthermore:
+Furthermore, Perl inspects the operands of the binary boolean operators to
+decide whether to use smart matching for each one by applying the above test to
+the operands:
=over 4
=item *
If EXPR is C<... && ...> or C<... and ...>, the test
-is applied recursively to both arguments. If I<both>
-arguments pass the test, then the argument is treated
-as boolean.
+is applied recursively to both operands. If I<both>
+operands pass the test, then the expression is treated
+as boolean; otherwise, smart matching is used.
=item *
If EXPR is C<... || ...>, C<... // ...> or C<... or ...>, the test
-is applied recursively to the first argument.
+is applied recursively to the first operand (which may be a
+higher-precedence AND operator, for example). If the first operand
+is to use smart matching, then both operands will do so; if it is
+not, then the second argument will not be either.
=back
These rules look complicated, but usually they will do what
-you want. For example you could write:
+you want. 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 $_ will be treated as boolean.
+
+Also:
+
+ when ([qw(foo bar)] && /baz/) { ... }
+
+will use smart matching because only I<one> of the operands is a boolean; the
+other uses smart matching, 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.
+
+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 smart match on C<'foo'>). For an alternation like
+this, an array ref will work, because this will instigate smart matching:
+
+ 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)>,
@@ -674,6 +716,45 @@ case to the next:
default { say '$foo does not contain a y' }
}
+=head3 Return value
+
+When a C<given> statement is also a valid expression (e.g.
+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's 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.
@@ -886,17 +967,18 @@ X<comment> X<line> X<#> X<preprocessor> X<eval>
Perl can process line directives, much like the C preprocessor. Using
this, one can control Perl's idea of filenames and line numbers in
error or warning messages (especially for strings that are processed
-with C<eval()>). The syntax for this mechanism is the same as for most
-C preprocessors: it matches the regular expression
+with C<eval()>). The syntax for this mechanism is almost the same as for
+most C preprocessors: it matches the regular expression
# example: '# line 42 "new_filename.plx"'
/^\# \s*
line \s+ (\d+) \s*
- (?:\s("?)([^"]+)\2)? \s*
+ (?:\s("?)([^"]+)\g2)? \s*
$/x
with C<$1> being the line number for the next line, and C<$3> being
-the optional filename (specified with or without quotes).
+the optional filename (specified with or without quotes). Note that
+no whitespace may precede the C<< # >>, unlike modern C preprocessors.
There is a fairly obvious gotcha included with the line directive:
Debuggers and profilers will only show the last source line to appear