Skip to content

Commit

Permalink
Edited chapter 4 for 2013 edition.
Browse files Browse the repository at this point in the history
  • Loading branch information
chromatic committed Aug 18, 2013
1 parent a6e6b97 commit fbcf05f
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 45 deletions.
63 changes: 33 additions & 30 deletions sections/operator_characteristics.pod
Expand Up @@ -5,13 +5,13 @@ X<operators; characteristics>

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.
other operators, the contexts it enforces, and the syntax it provides.

C<perldoc perlop> and C<perldoc perlsyn> 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.
Perl's operators, but the documentation assumes you're already familiar with a
few essential computer science concepts. These ideas sound complicated, but
they use complex names for ideas you already understand, even if you've never
thought about them. If you can do elementary math in your head, you'll do fine.

=head2 Precedence

Expand All @@ -20,17 +20,19 @@ X<precedence>

The I<precedence> 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>.
Remember basic math? Multiply and divide before you add and subtract. That's
precedence. Because the precedence of multiplication is higher than the
precedence of addition, in Perl 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>.

C<perldoc perlop> 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<perldoc perlop> contains a table of precedence. Skim it a few times, but
don't bother memorizing it (almost no one does). Spend your time simplifying
your code where you can and then adding clarifying parentheses where you need
them.

In cases where two operators have the same precedence, other factors such as
associativity (L<associativity>) and fixity (L<fixity>) break the tie.
Expand All @@ -48,11 +50,12 @@ The I<associativity> 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.
C<2> to the 81st power. As usual, grouping with parentheses will let you change
the order of evaluation.

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.
If you memorize only the precedence and associativity of the common
mathematical operators, you'll be fine. Simplify your code and you won't have
to memorize other associativities.

=begin sidebar

Expand All @@ -65,9 +68,9 @@ The core C<B::Deparse> module is an invaluable debugging tool. Run C<perl
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>.
Beware that Perl's optimizer will simplify mathematical operations using
constant values. To work around this, use named variables instead, as in C<$x
** $y ** $z>.

=end sidebar

Expand All @@ -87,16 +90,15 @@ The I<arity> of an operator is the number of operands on which it operates. A
I<nullary> operator operates on zero operands. A I<unary> operator operates on
one operand. A I<binary> operator operates on two operands. A I<trinary>
operator operates on three operands. A I<listary> operator operates on a list
of operands. An operator's documentation and examples should make its arity
clear.
of operands.

For example, the arithmetic operators are binary operators, and are usually
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>).
The arithmetic operators are binary operators and are usually 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>).

Perl novices often find confusion between the interaction of listary
operators--especially function calls--and nested expressions. Where parentheses
Expand Down Expand Up @@ -131,7 +133,8 @@ X<fixity; circumfix>
X<postcircumfix>
X<fixity; postcircumfix>

An operator's I<fixity> is its position relative to its operands:
An operator's I<fixity>N<Don't memorize all of these words. Just remember what
they mean.> is its position relative to its operands:

X<C<.>; infix operator>
X<C<.=>; infix operator>
Expand Down Expand Up @@ -161,9 +164,9 @@ X<C<->; prefix operator>
X<C<!>; prefix operator>
X<C<!!>; prefix operator>

=item * I<Prefix> operators precede their operators. I<Postfix> operators
follow. These operators tend to be unary, such as mathematic negation (C<-$x>),
boolean negation (C<!$y>), and postfix increment (C<$z++>).
=item * I<Prefix> operators precede their operands. I<Postfix> operators follow
their operands. These operators tend to be unary, such as mathematic negation
(C<-$x>), boolean negation (C<!$y>), and postfix increment (C<$z++>).

X<C<()>; circumfix operator>
X<C<{}>; circumfix operator>
Expand Down
49 changes: 34 additions & 15 deletions sections/operator_types.pod
Expand Up @@ -3,8 +3,8 @@
Z<operator_types>

Perl operators provide value contexts (L<value_contexts>) 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.
To choose the appropriate operator, you must know the values of the operands
you provide as well as the value you expect to receive.

=head2 Numeric Operators

Expand Down Expand Up @@ -41,8 +41,8 @@ X<C<-->; numeric operator>

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<->), multiplication (C<*>), division (C</>), exponentiation (C<**>), and
modulo (C<%>), their in-place variants (C<+=>, C<-=>, C<*=>, C</=>, C<**=>, and
C<%=>), and both postfix and prefix auto-decrement (C<-->).

The auto-increment operator has special string behavior
Expand Down Expand Up @@ -132,8 +132,8 @@ X<short-circuiting>

Logical operators impose a boolean context on their operands. These operators
are C<&&>, C<and>, C<||>, and C<or>. All are infix and all exhibit
I<short-circuiting> behavior (L<short_circuiting>). The word variants have
lower precedence than their punctuation forms.
I<short-circuiting> behavior (L<short_circuiting>). The word forms have lower
precedence than their punctuation forms.

The defined-or operator, C<//>, tests the I<definedness> of its operand. Unlike
C<||> which tests the I<truth> of its operand, C<//> evaluates to a true value
Expand Down Expand Up @@ -162,8 +162,8 @@ the third otherwise:

=end programlisting

The prefix C<!> and C<not> operators return the logical opposite of the boolean
value of their operands. C<not> is a lower precedence version of C<!>.
The prefix C<!> and C<not> operators return the logical opposites of the
boolean values of their operands. C<not> is a lower precedence version of C<!>.

The C<xor> operator is an infix operator which evaluates to the exclusive-or of
its operands.
Expand Down Expand Up @@ -212,8 +212,8 @@ X<C<++>; auto-increment operator>
The auto-increment operator has special behavior. When used on a value with a
numeric component (L<cached_coercions>), 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<a> becomes C<b>, C<zz>
becomes C<aaa>, and C<a9> becomes C<b0>.
the operator increments the value's string component such that C<a> becomes
C<b>, C<zz> becomes C<aaa>, and C<a9> becomes C<b0>.

=begin programlisting

Expand All @@ -238,11 +238,12 @@ X<operators; repetition>
X<operators; C<x>>
X<C<x>; repetition operator>

The repetition operator (C<x>) 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.
The repetition operator (C<x>) is an infix operator with complex behavior. When
evaluated in list context with a list as its first operand, it evaluates to
that list repeated the number of times specified by its second operand. When
evaluated in list context with a scalar as its first operand, 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:
Expand Down Expand Up @@ -314,3 +315,21 @@ order.

The fat comma operator (C<< => >>) also automatically quotes any bareword used
as its left operand (L<hashes>).

X<operators; triple-dot>
X<operators; whatever>
X<operators; C<...>>

The I<triple-dot> or I<whatever> operator stands in for a single statement. It
is nullary and has neither precedence nor associativity. It parses, but when
executed it throws an exception with the string C<Unimplemented>. This makes a
great placeholder in example code you don't expect anyone to execute:

=begin programlisting

sub some_example {
# implement this yourself
...
}

=end programlisting

0 comments on commit fbcf05f

Please sign in to comment.