diff --git a/sections/chapter_04.pod b/sections/chapter_04.pod index 1f75f279..780fae53 100644 --- a/sections/chapter_04.pod +++ b/sections/chapter_04.pod @@ -4,22 +4,13 @@ Z X X -An accurate, if irreverent, description of Perl is an "operator-oriented -language". The interaction of operators with their operands gives Perl its -expressivity and power. Understanding Perl requires understanding its -operators and how they behave. For the sake of this discussion, a working -definition of a Perl I is a series of one or more symbols used as -part of the syntax of a language. Each operator operates on zero or more -I; this definition is circular, as an operand is a value on which an -operator operates. +Some people call Perl an "operator-oriented language". To understand a Perl +program, you must understand how its operators interact with their operands. -=begin sidebar - -The most accurate definition of operators is "What's in C", but even -that leaves out some operators in C and includes builtins. Don't get -too attached to a single definition. - -=end sidebar +A Perl I is a series of one or more symbols used as part of the +syntax of a language. Each operator operates on zero or more I. Think +of an operator as a special sort of function the parser understands and its +operands as arguments. L diff --git a/sections/operator_characteristics.pod b/sections/operator_characteristics.pod index 74c439da..10447776 100644 --- a/sections/operator_characteristics.pod +++ b/sections/operator_characteristics.pod @@ -3,38 +3,37 @@ Z X -Both C and C provide voluminous information -about the behavior of Perl's operators. Even so, what they I explain is -more important to their understanding. The documentation assumes you have a -familiarity with several concepts in language design. These concepts may sound -imposing at first, but they're straightforward to understand. - Every operator possesses several important characteristics which govern its behavior: the number of operands on which it operates, its relationship to other operators, and its syntactic possibilities. +C and C provide voluminous information about +Perl's operators, but the documentation assumes you're already familiar with +some details of how they work. The essential computer science concepts may +sound imposing at first, but once you get past their names, they're +straightforward. You already understand them implicitly. + =head2 Precedence Z X -The I of an operator helps determine when Perl should evaluate it -in an expression. Evaluation order proceeds from highest to lowest precedence. -For example, because the precedence of multiplication is higher than the -precedence of addition, C<7 + 7 * 10> evaluates to C<77>, not C<140>. You may -force the evaluation of some operators before others by grouping their -subexpressions in parentheses; C<(7 + 7) * 10> I evaluate to C<140>, as -the addition operation becomes a single unit which must evaluate fully before -multiplication can occur. +The I of an operator governs when Perl should evaluate it in an +expression. Evaluation order proceeds from highest to lowest precedence. +Because the precedence of multiplication is higher than the precedence of +addition, C<7 + 7 * 10> evaluates to C<77>, not C<140>. + +To force the evaluation of some operators before others, group their +subexpressions in parentheses. In C<(7 + 7) * 10>, grouping the addition into a +single unit forces its evaluation before the multiplication. The result is +C<140>. -In case of a tie--where two operators have the same precedence--other factors -such as fixity (L) and associativity (L) break the tie. +C contains a table of precedence. Read it, understand it, but +don't bother memorizing it (almost no one does). Spend your time keeping your +expressions simple, and then add parentheses to clarify your intent. -C contains a table of precedence. Almost no one has this table -memorized. The best way to manage precedence is to keep your expressions -simple. The second best way is to use parentheses to clarify precedence in -complex expressions. If you find yourself drowning in a sea of parentheses, -see the first rule again. +In cases where two operators have the same precedence, other factors such as +associativity (L) and fixity (L) break the tie. =head2 Associativity @@ -46,14 +45,14 @@ X X The I of an operator governs whether it evaluates from left to -right or right to left. Addition is left associative, such that C<2 + 3 + 4> -evaluates C<2 + 3> first, then adds C<4> to the result. Exponentiation is -right associative, such that C<2 ** 3 ** 4> evaluates C<3 ** 4> first, then -raises C<2> to the 81st power. +right or right to left. Addition is left associative, such that C<2 + 3 + 4> +evaluates C<2 + 3> first, then adds C<4> to the result. Exponentiation is right +associative, such that C<2 ** 3 ** 4> evaluates C<3 ** 4> first, then raises +C<2> to the 81st power. -Simplifying complex expressions and using parentheses to demonstrate your -intent is more important than memorizing associativity tables. Even so, -memorizing the associativity of the mathematic operators is worthwhile. +It's worth your time to memorize the precedence and associativity of the common +mathematical operators, but again simplicity rules the day. Use parentheses to +make your intentions clear. =begin sidebar @@ -61,12 +60,14 @@ X> X X -The core C module can rewrite snippets of code to demonstrate -exactly how Perl handles operator precedence and associativity; run C on a snippet of code. (The C<-p> flag adds extra grouping -parentheses which often clarify evaluation order.) Beware that Perl's optimizer -will simplify mathematical operations as given as examples earlier in this -section; use variables instead, as in C<$x ** $y ** $z>. +The core C module is an invaluable debugging tool. Run C on a snippet of code to see exactly how Perl handles operator +precedence and associativity. The C<-p> flag adds extra grouping parentheses +which often clarify evaluation order. + +Beware that Perl's optimizer will simplify mathematical operations as given as +examples earlier in this section; use variables instead, as in C<$x ** $y ** +$z>. =end sidebar @@ -83,27 +84,23 @@ X X The I of an operator is the number of operands on which it operates. A -I operator operates on zero operands. A I operator operates on -one operand. A I operator operates on two operands. A I -operator operates on three operands. A I operator operates on a list -of operands. - -There's no single good rule for determining the arity of an operator, other -than the fact that most operate on two, many, or one operands. The operator's -documentation should make this clear. +I operator operates on zero operands. A I operator operates on +one operand. A I operator operates on two operands. A I +operator operates on three operands. A I operator operates on a list +of operands. An operator's documentation and examples should make its arity +clear. For example, the arithmetic operators are binary operators, and are usually -left associative. C<2 + 3 - 4> evaluates C<2 + 3> first; addition and +left associative. C<2 + 3 - 4> evaluates C<2 + 3> first; addition and subtraction have the same precedence, but they're left associative and binary, so the proper evaluation order applies the leftmost operator (C<+>) to the leftmost two operands (C<2> and C<3>) with the leftmost operator (C<+>), then applies the rightmost operator (C<->) to the result of the first operation and the rightmost operand (C<4>). -One common source of confusion for Perl novices is the interaction of listary -operators (especially function calls) with nested expressions. Using grouping -parentheses to clarify your intent, yet watch out for confusion in code such -as: +Perl novices often find confusion between the interaction of listary +operators--especially function calls--and nested expressions. Where parentheses +usually help, beware of the parsing complexity of: =begin programlisting @@ -112,10 +109,11 @@ as: =end programlisting -... as Perl 5 happily interprets the parentheses as postcircumfix (L) -operators denoting the arguments to C, not circumfix parentheses grouping -an expression to change precedence. In other words, the code prints the value -C<6> and evaluates to the return value of C multiplied by C<4>. +... which prints the value C<6> and (probably) evaluates as a whole to C<4> +(the return value of C multiplied by C<4>). Perl's parser happily +interprets the parentheses as postcircumfix (L) operators denoting the +arguments to C, not circumfix parentheses grouping an expression to change +precedence. =head2 Fixity @@ -150,7 +148,7 @@ X; infix operator> =over 4 -=item I operators appear between their operands. Most mathematical +=item I operators appear between their operands. Most mathematical operators are infix operators, such as the multiplication operator in C<$length * $width>. @@ -163,9 +161,9 @@ X; prefix operator> X; prefix operator> X; prefix operator> -=item I operators appear before their operators and I -operators appear after. These operators tend to be unary, such as mathematic -negation (C<-$x>), boolean negation (C), and postfix increment (C<$z++>). +=item I operators precede their operators. I operators follow. +These operators tend to be unary, such as mathematic negation (C<-$x>), boolean +negation (C), and postfix increment (C<$z++>). X; circumfix operator> X; circumfix operator> @@ -175,14 +173,15 @@ X; circumfix operator> X; circumfix operator> X; circumfix operator> -=item I operators surround their operands. Examples include the -anonymous hash constructor (C<{ ... }>) and quoting operators (C). +=item I operators surround their operands, as with the anonymous +hash constructor (C<{ ... }>) and quoting operators (C). X; postcircumfix operator> X; postcircumfix operator> X; postcircumfix operator> =item I operators follow certain operands and surround others, -as with hash or array element access (C<$hash{ ... }> and C<$array[ ... ]>). +as seen in hash and array element access (C<$hash{ ... }> and C<$array[ ... +]>). =back diff --git a/sections/operator_types.pod b/sections/operator_types.pod index 93fe8f2b..35c00c4b 100644 --- a/sections/operator_types.pod +++ b/sections/operator_types.pod @@ -2,12 +2,9 @@ Z -Perl's pervasive contexts--especially value contexts -(L)--extend to the behavior of its operators. Perl operators -provide value contexts to their operands. Choosing the most appropriate -operator for a given situation requires you to understand what type of value -you expect to receive as well as the type of values on which you wish to -operate. +Perl operators provide value contexts (L) to their operands. +To choose the appropriate operator, understand the values of the operands you +provide as well as the value you expect to receive. =head2 Numeric Operators @@ -42,14 +39,14 @@ X; numeric operator> X> X; numeric operator> -The numeric operators impose numeric contexts on their operands. They consist -of the standard arithmetic operators such as addition (C<+>), subtraction +Numeric operators impose numeric contexts on their operands. These operators +are the standard arithmetic operators such as addition (C<+>), subtraction (C<->), multiplication (C<*>), division (C), exponentiation (C<**>), modulo (C<%>), their in-place variants (C<+=>, C<-=>, C<*=>, C, C<**=>, and -C<%=>), and auto-decrement (C<-->), whether postfix or prefix. +C<%=>), and both postfix and prefix auto-decrement (C<-->). -While the auto-increment operator may seem like a numeric operator, it has -special string behavior (L). +The auto-increment operator has special string behavior +(L). X> X> @@ -84,9 +81,9 @@ X; string operator> X> X; string operator> -The string operators impose string contexts on their operands. They consist -of the positive and negative regular expression binding operators (C<=~> and -C, respectively), and the concatenation operator (C<.>). +String operators impose string contexts on their operands. These operators are +positive and negative regular expression binding (C<=~> and C, +respectively), and concatenation (C<.>). X> X> @@ -103,10 +100,10 @@ X; string comparison operator> X; string comparison operator> X; string comparison operator> -Several comparison operators impose string contexts upon their operands. -These are string equality (C), string inequality (C), greater than -(C), less than (C), greater than or equal to (C), less than or -equal to (C), and the string sort comparison operator (C). +Several comparison operators impose string contexts upon their operands. These +are string equality (C), string inequality (C), greater than (C), +less than (C), greater than or equal to (C), less than or equal to +(C), and the string sort comparison operator (C). =head2 Logical Operators @@ -133,16 +130,15 @@ X X X -The logical operators treat their operands in a boolean context. The C<&&> and -C operators test that both expressions are logically true, while the C<||> -and C operators test that either expression is true. All four are infix -operators. All four exhibit I behavior -(L). +Logical operators impose a boolean context on their operands. These operators +are C<&&>, C, C<||>, and C. All are infix and all exhibit +I behavior (L). The word variants have +lower precedence than their punctuation forms. -The defined-or operator, C, tests the I of its operand. -Unlike C<||> which tests the truth value of its operand, C evaluates to a -true value if its operand evaluates to a numeric zero or the empty string. -This is especially useful for setting default parameter values: +The defined-or operator, C, tests the I of its operand. Unlike +C<||> which tests the I of its operand, C evaluates to a true value +even if its operand evaluates to a numeric zero or the empty string. This is +especially useful for setting default parameter values: =begin programlisting @@ -156,9 +152,9 @@ This is especially useful for setting default parameter values: X; ternary conditional operator> -The ternary conditional operator (C) takes three operands. It evaluates -the first in boolean context and evaluates to the second if the first is true -and the third otherwise: +The ternary conditional operator (C) takes three operands. It evaluates the +first in boolean context and evaluates to the second if the first is true and +the third otherwise: =begin programlisting @@ -166,9 +162,8 @@ and the third otherwise: =end programlisting -The C and C operators return the logical opposite of the boolean value -of their operands. C has a lower precedence than C. These are prefix -operators. +The prefix C and C operators return the logical opposite of the boolean +value of their operands. C is a lower precedence version of C. The C operator is an infix operator which evaluates to the exclusive-or of its operands. @@ -199,11 +194,11 @@ X; bitwise operator> X<<< C<< EE= >>; bitwise operator >>> X<<< C<< EE= >>; bitwise operator >>> -The bitwise operators treat their operands numerically at the bit level. These -are uncommon in most Perl 5 programs. They consist of left shift (C<< << >>), -right shift (C<< >> >>), bitwise and (C<&>), bitwise or (C<|>), and bitwise xor -(C<^>), as well as their in-place variants (C<< <<= >>, C<< >>= >>, C<&=>, -C<|=>, and C<^=>). +Bitwise operators treat their operands numerically at the bit level. These +operations are uncommon. They consist of left shift (C<< << >>), right shift +(C<< >> >>), bitwise and (C<&>), bitwise or (C<|>), and bitwise xor (C<^>), as +well as their in-place variants (C<< <<= >>, C<< >>= >>, C<&=>, C<|=>, and +C<^=>). =head2 Special Operators @@ -214,11 +209,11 @@ X X> X; auto-increment operator> -The auto-increment operator has a special case. If anything has ever used a -variable in a numeric context (L), it increments the numeric -value of that variable. If the variable is obviously a string (and has never -been evaluated in a numeric context), the string value increments with a carry, -such that C increments to C, C to C, and C to C. +The auto-increment operator has special behavior. When used on a value with a +numeric component (L), the operator increments that numeric +component. If the value is obviously a string (and has no numeric component), +the operator increments that string value such that C becomes C, C +becomes C, and C becomes C. =begin programlisting @@ -243,13 +238,14 @@ X X> X; repetition operator> -The repetition operator (C) is an infix operator. In list context, its -behavior changes based on its first operand. When given a list, it evaluates -to that list repeated the number of times specified by its second operand. -When given a scalar, it produces a string consisting of the string value of -its first operand concatenated to itself the number of times specified by its -second operand. In scalar context, the operator always produces a concatenated -string repeated appropriately. +The repetition operator (C) is an infix operator with complex behavior. In +list context, when given a list, it evaluates to that list repeated the number +of times specified by its second operand. In list context when given a scalar, +it produces a string consisting of the string value of its first operand +concatenated to itself the number of times specified by its second operand. + +In scalar context, the operator always produces a concatenated string repeated +appropriately. For example: @@ -274,8 +270,7 @@ X X> X; range operator> -The I operator (C<..>) is an infix operator which produces a list of -items in list context: +The infix I operator (C<..>) produces a list of items in list context: =begin programlisting @@ -283,19 +278,18 @@ items in list context: =end programlisting -It can produce simple, incrementing ranges (whether integers or -autoincrementing strings), but it cannot intuit patterns or more complex -ranges. +It can produce simple, incrementing ranges (both as integers or strings), but +it cannot intuit patterns or more complex ranges. X X X; flip-flop operator> -In boolean context, the range operator becomes the I operator. This -operator returns a false value until its left operand is true, then it stays -true until its right operand is true, after which it is false again until the -left operand is true again. Thus you could quote the body of a pedantically -formatted email with: +In boolean context, the range operator becomes the I operator. This +operator produces a false value until its left operand is true. That value +stays true until the right operand is true, after which the value is false +again until the left operand is true again. Imagine parsing the text of a +formal letter with: =begin programlisting @@ -312,10 +306,10 @@ X; operator> X<<< operators; C<< =E >> >>> X<<< C<< =E >>; fat comma operator >>> -The I operator (C<,>) is an infix operator. In scalar context it +The I operator (C<,>) is an infix operator. In scalar context it evaluates its left operand then returns the value produced by evaluating its -right operand. In list context, it evaluates both operands in left-to-right +right operand. In list context, it evaluates both operands in left-to-right order. -The fat comma operator (C<< => >>) behaves the same way, except that it -automatically quotes any bareword used as its left operand (L). +The fat comma operator (C<< => >>) also automatically quotes any bareword used +as its left operand (L).