diff options
Diffstat (limited to 'pod/perlop.pod')
-rw-r--r-- | pod/perlop.pod | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/pod/perlop.pod b/pod/perlop.pod index 79e7bd9fe3..9dc927804f 100644 --- a/pod/perlop.pod +++ b/pod/perlop.pod @@ -36,7 +36,8 @@ C<(2 + 4) * 5>. So the expression yields C<2 + 20 == 22>, rather than C<6 * 5 == 30>. I<Operator associativity> defines what happens if a sequence of the same -operators is used one after another: whether they will be grouped at the left +operators is used one after another: +usually that they will be grouped at the left or the right. For example, in C<9 - 3 - 2>, subtraction is left associative, so C<9 - 3> is grouped together as the left-hand operand of the second subtraction, rather than C<3 - 2> being grouped together as the right-hand @@ -59,6 +60,47 @@ special evaluation rules that can result in an operand not being evaluated at all; in general, the top-level operator in an expression has control of operand evaluation. +Some comparison operators, as their associativity, I<chain> with others +of the same precedence. This means that each comparison is performed +on the two arguments surrounding it, with each interior argument taking +part in two comparisons, and the comparison results are implicitly ANDed. +Thus S<C<"$a E<lt> $b E<lt>= $c">> behaves exactly like S<C<"$a E<lt> +$b && $b E<lt>= $c">>, assuming that C<"$b"> is as simple a scalar as +it looks. The ANDing short-circuits just like C<"&&"> does, stopping +the sequence of comparisons as soon as one yields false. + +In a chained comparison, each argument expression is evaluated at most +once, even if it takes part in two comparisons. (It is not evaluated +at all if the short-circuiting means that it's not required for any +comparisons.) This matters if the computation of an interior argument +is expensive or non-deterministic. For example, + + if($a < expensive_sub() <= $c) { ... + +is not entirely like + + if($a < expensive_sub() && expensive_sub() <= $c) { ... + +but instead closer to + + my $tmp = expensive_sub(); + if($a < $tmp && $tmp <= $c) { ... + +in that the subroutine is only called once. However, it's not exactly +like this latter code either, because the chained comparison doesn't +actually involve any temporary variable (named or otherwise): there is +no assignment. This doesn't make much difference where the expression +is a call to an ordinary subroutine, but matters more with an lvalue +subroutine, or if the argument expression yields some unusual kind of +scalar by other means. For example, if the argument expression yields +a tied scalar, then the expression is evaluated to produce that scalar +at most once, but the value of that scalar may be fetched up to twice, +once for each comparison in which it is actually used. + +Some operators are instead non-associative, meaning that it is a syntax +error to use a sequence of those operators of the same precedence. +For example, S<C<"$a .. $b .. $c">> is an error. + Perl operators have the following associativity and precedence, listed from highest precedence to lowest. Operators borrowed from C keep the same precedence relationship with each other, even where @@ -518,17 +560,8 @@ than or equal to the right argument. X<< ge >> A sequence of relational operators, such as S<C<"$a E<lt> $b E<lt>= -$c">>, does not group in accordance with left or right associativity, -which would produce the almost-useless result of using the truth-value -result of one comparison as a comparand in another comparison. Instead -the comparisons are I<chained>: each comparison is performed on the -two arguments surrounding it, with each interior argument taking part -in two comparisons, and the comparison results are implicitly ANDed. -Thus S<C<"$a E<lt> $b E<lt>= $c">> behaves very much like S<C<"$a E<lt> -$b && $b E<lt>= $c">>. The ANDing short-circuits just like C<"&&"> -does, stopping the sequence of comparisons as soon as one yields false. -Each argument expression is evaluated at most once, even if it takes -part in two comparisons. +$c">>, performs chained comparisons, in the manner described above in +the section L</"Operator Precedence and Associativity">. =head2 Equality Operators X<equality> X<equal> X<equals> X<operator, equality> @@ -550,8 +583,8 @@ to the right argument. X<ne> A sequence of the above equality operators, such as S<C<"$a == $b == -$c">>, performs chained comparisons, in the same manner as described in -the previous section for relational operators. +$c">>, performs chained comparisons, in the manner described above in +the section L</"Operator Precedence and Associativity">. Binary C<< "<=>" >> returns -1, 0, or 1 depending on whether the left argument is numerically less than, equal to, or greater than the right |