Add tests for the C<my $x if foo> deprecation, and change the
[p5sagit/p5-mst-13.2.git] / pod / perlop.pod
index cd36ec1..86cb294 100644 (file)
@@ -2,7 +2,24 @@
 
 perlop - Perl operators and precedence
 
-=head1 SYNOPSIS
+=head1 DESCRIPTION
+
+=head2 Operator Precedence and Associativity
+
+Operator precedence and associativity work in Perl more or less like
+they do in mathematics.
+
+I<Operator precedence> means some operators are evaluated before
+others.  For example, in C<2 + 4 * 5>, the multiplication has higher
+precedence so C<4 * 5> is evaluated first yielding C<2 + 20 ==
+22> and not C<6 * 5 == 30>.
+
+I<Operator associativity> defines what happens if a sequence of the
+same operators is used one after another: whether the evaluator will
+evaluate the left operations first or the right.  For example, in C<8
+- 4 - 2>, subtraction is left associative so Perl evaluates the
+expression left to right.  C<8 - 4> is evaluated first making the
+expression C<4 - 2 == 2> and not C<8 - 2 == 6>.
 
 Perl operators have the following associativity and precedence,
 listed from highest precedence to lowest.  Operators borrowed from
@@ -40,8 +57,6 @@ In the following sections, these operators are covered in precedence order.
 
 Many operators can be overloaded for objects.  See L<overload>.
 
-=head1 DESCRIPTION
-
 =head2 Terms and List Operators (Leftward)
 
 A TERM has the highest precedence in Perl.  They include variables,
@@ -83,8 +98,18 @@ Also note that
 
     print ($foo & 255) + 1, "\n";
 
-probably doesn't do what you expect at first glance.  See
-L<Named Unary Operators> for more discussion of this.
+probably doesn't do what you expect at first glance.  The parentheses
+enclose the argument list for C<print> which is evaluated (printing
+the result of C<$foo & 255>).  Then one is added to the return value
+of C<print> (usually 1).  The result is something like this:
+
+    1 + 1, "\n";    # Obviously not what you meant.
+
+To do what you meant properly, you must write:
+
+    print(($foo & 255) + 1, "\n");
+
+See L<Named Unary Operators> for more discussion of this.
 
 Also parsed as terms are the C<do {}> and C<eval {}> constructs, as
 well as subroutine and method calls, and the anonymous
@@ -110,9 +135,14 @@ or a class name (that is, a package name).  See L<perlobj>.
 
 =head2 Auto-increment and Auto-decrement
 
-"++" and "--" work as in C.  That is, if placed before a variable, they
-increment or decrement the variable before returning the value, and if
-placed after, increment or decrement the variable after returning the value.
+"++" and "--" work as in C.  That is, if placed before a variable,
+they increment or decrement the variable by one before returning the
+value, and if placed after, increment or decrement after returning the
+value.
+
+    $i = 0;  $j = 0;
+    print $i++;  # prints 0
+    print ++$j;  # prints 1
 
 The auto-increment operator has a little extra builtin magic to it.  If
 you increment a variable that is numeric, or that has ever been used in
@@ -157,7 +187,7 @@ example, C<0666 & ~027> is 0640.  (See also L<Integer Arithmetic> and
 L<Bitwise String Operators>.)  Note that the width of the result is
 platform-dependent: ~0 is 32 bits wide on a 32-bit platform, but 64
 bits wide on a 64-bit platform, so if you are expecting a certain bit
-width, remember use the & operator to mask off the excess bits.
+width, remember to use the & operator to mask off the excess bits.
 
 Unary "+" has no effect whatsoever, even on strings.  It is useful
 syntactically for separating a function name from a parenthesized expression
@@ -251,8 +281,7 @@ of bits is also undefined.
 =head2 Named Unary Operators
 
 The various named unary operators are treated as functions with one
-argument, with optional parentheses.  These include the filetest
-operators, like C<-f>, C<-M>, etc.  See L<perlfunc>.
+argument, with optional parentheses.
 
 If any list operator (print(), etc.) or any unary operator (chdir(), etc.)
 is followed by a left parenthesis as the next token, the operator and
@@ -277,6 +306,11 @@ but, because * is higher precedence than named operators:
     rand (10) * 20;    # (rand 10) * 20
     rand +(10) * 20;   # rand (10 * 20)
 
+Regarding precedence, the filetest operators, like C<-f>, C<-M>, etc. are
+treated like named unary operators, but they don't follow this functional
+parenthesis rule.  That means, for example, that C<-f($file).".bak"> is
+equivalent to C<-f "$file.bak">.
+
 See also L<"Terms and List Operators (Leftward)">.
 
 =head2 Relational Operators
@@ -382,12 +416,12 @@ tests the left hand side's definedness instead of its truth.  Thus, C<$a // $b>
 is similar to C<defined($a) || $b> (except that it returns the value of C<$a> 
 rather than the value of C<defined($a)>) and is exactly equivalent to 
 C<defined($a) ? $a : $b>.  This is very useful for providing default values
-for variables.  If you actually want to test if at least one of C<$a> and C<$b> is
-defined, use C<defined($a // $b)>.
+for variables.  If you actually want to test if at least one of C<$a> and 
+C<$b> is defined, use C<defined($a // $b)>.
 
-The C<||>, C<//> and C<&&> operators differ from C's in that, rather than returning
-0 or 1, they return the last value evaluated.  Thus, a reasonably portable
-way to find out the home directory might be:
+The C<||>, C<//> and C<&&> operators return the last value evaluated
+(unlike C's C<||> and C<&&>, which return 0 or 1). Thus, a reasonably
+portable way to find out the home directory might be:
 
     $home = $ENV{'HOME'} // $ENV{'LOGDIR'} //
        (getpwuid($<))[7] // die "You're homeless!\n";
@@ -418,10 +452,10 @@ Using "or" for assignment is unlikely to do what you want; see below.
 =head2 Range Operators
 
 Binary ".." is the range operator, which is really two different
-operators depending on the context.  In list context, it returns an
+operators depending on the context.  In list context, it returns a
 list of values counting (up by ones) from the left value to the right
 value.  If the left value is greater than the right value then it
-returns the empty array.  The range operator is useful for writing
+returns the empty list.  The range operator is useful for writing
 C<foreach (1..10)> loops and for doing slice operations on arrays. In
 the current implementation, no temporary array is created when the
 range operator is used as the expression in C<foreach> loops, but older
@@ -458,23 +492,42 @@ sequence number in a range has the string "E0" appended to it, which
 doesn't affect its numeric value, but gives you something to search
 for if you want to exclude the endpoint.  You can exclude the
 beginning point by waiting for the sequence number to be greater
-than 1.  If either operand of scalar ".." is a constant expression,
-that operand is implicitly compared to the C<$.> variable, the
-current line number.  Examples:
+than 1.
+
+If either operand of scalar ".." is a constant expression,
+that operand is considered true if it is equal (C<==>) to the current
+input line number (the C<$.> variable).
+
+To be pedantic, the comparison is actually C<int(EXPR) == int(EXPR)>,
+but that is only an issue if you use a floating point expression; when
+implicitly using C<$.> as described in the previous paragraph, the
+comparison is C<int(EXPR) == int($.)> which is only an issue when C<$.>
+is set to a floating point value and you are not reading from a file.
+Furthermore, C<"span" .. "spat"> or C<2.18 .. 3.14> will not do what
+you want in scalar context because each of the operands are evaluated
+using their integer representation.
+
+Examples:
 
 As a scalar operator:
 
-    if (101 .. 200) { print; } # print 2nd hundred lines
-    next line if (1 .. /^$/);  # skip header lines
+    if (101 .. 200) { print; } # print 2nd hundred lines, short for
+                               #   if ($. == 101 .. $. == 200) ...
+    next line if (1 .. /^$/);  # skip header lines, short for
+                               #   ... if ($. == 1 .. /^$/);
     s/^/> / if (/^$/ .. eof());        # quote body
 
     # parse mail messages
     while (<>) {
         $in_header =   1  .. /^$/;
-        $in_body   = /^$/ .. eof();
-       # do something based on those
+        $in_body   = /^$/ .. eof;
+        if ($in_header) {
+            # ...
+        } else { # in body
+            # ...
+        }
     } continue {
-       close ARGV if eof;              # reset $. each file
+        close ARGV if eof;             # reset $. each file
     }
 
 As a list operator:
@@ -502,6 +555,11 @@ in the sequence that the magical increment would produce, the sequence
 goes until the next value would be longer than the final value
 specified.
 
+Because each operand is evaluated in integer form, C<2.18 .. 3.14> will
+return two elements in list context.
+
+    @list = (2.18 .. 3.14); # same as @list = (2 .. 3);
+
 =head2 Conditional Operator
 
 Ternary "?:" is the conditional operator, just as in C.  It works much
@@ -595,9 +653,10 @@ argument and returns that value.  This is just like C's comma operator.
 In list context, it's just the list argument separator, and inserts
 both its arguments into the list.
 
-The => digraph is mostly just a synonym for the comma operator.  It's useful for
-documenting arguments that come in pairs.  As of release 5.001, it also forces
-any word to the left of it to be interpreted as a string.
+The C<< => >> operator is a synonym for the comma, but forces any word
+to its left to be interpreted as a string (as of 5.001). It is helpful
+in documenting the correspondence between keys and values in hashes,
+and other paired elements in lists.
 
 =head2 List Operators (Rightward)
 
@@ -743,6 +802,9 @@ and in transliterations.
     \c[                control char    (ESC)
     \N{name}   named Unicode character
 
+B<NOTE>: Unlike C and other languages, Perl has no \v escape sequence for
+the vertical tab (VT - ASCII 11).
+
 The following escape sequences are available in constructs that interpolate
 but not in transliterations.
 
@@ -1123,10 +1185,10 @@ but leave its STDOUT to come out the old STDERR:
     $output = `cmd 3>&1 1>&2 2>&3 3>&-`;
 
 To read both a command's STDOUT and its STDERR separately, it's easiest
-and safest to redirect them separately to files, and then read from those
-files when the program is done:
+to redirect them separately to files, and then read from those files
+when the program is done:
 
-    system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr");
+    system("program args 1>program.stdout 2>program.stderr");
 
 Using single-quote as a delimiter protects the command from Perl's
 double-quote interpolation, passing it on to the shell instead:
@@ -1178,7 +1240,8 @@ equivalent to:
 
     split(' ', q/STRING/);
 
-the difference being that it generates a real list at compile time.  So
+the differences being that it generates a real list at compile time, and
+in scalar context it returns the last element in the list.  So
 this expression:
 
     qw(foo bar baz)
@@ -1666,7 +1729,7 @@ alphanumeric char, as in:
 
 In the RE above, which is intentionally obfuscated for illustration, the
 delimiter is C<m>, the modifier is C<mx>, and after backslash-removal the
-RE is the same as for C<m/ ^ a s* b /mx>).  There's more than one 
+RE is the same as for C<m/ ^ a \s* b /mx>.  There's more than one 
 reason you're encouraged to restrict your delimiters to non-alphanumeric,
 non-whitespace choices.