Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Re^3: Why does the first $c evaluate to the incremented value in [$c, $c += $_] ?

by Eily (Vicar)
on Mar 04, 2014 at 23:29 UTC ( #1077009=note: print w/replies, xml ) Need Help??

in reply to Re^2: Why does the first $c evaluate to the incremented value in [$c, $c += $_] ?
in thread Why does the first $c evaluate to the incremented value in [$c, $c += $_] ?

That's because decorate has an even higher precedence (on the left of any operator except commas, and unless parenthesis are involved) so what happens is actually:

(decorate("foo"), decorate("bar").'!') ((return $decorated_foo), (return $decorated_bar.'!')) ((return $decorated_foo), (return $decorated_bar_with_exclamation_mark +)) ($decorated_foo, (return $decorated_bar_with_exclamation_mark)) ($decorated_foo, $decorated_bar_with_exclamation_mark)
(This is of course, not actual code, but just a representation)
So first the calls to decorate are resolved, then the concatenation, and at last the values are added to the list. But the concatenation does not happen last.

Edit: "removed" a bit about precedence being higher on the left of some operators, because it's late, and I'm not sure about what I'm saying.

Replies are listed 'Best First'.
Re^4: Why does the first $c evaluate to the incremented value in [$c, $c += $_] ?
by smls (Friar) on Mar 05, 2014 at 00:34 UTC

    D'oh... Yeah, you're right.

    So, for the record, the evaluation order is in fact well-defined: It strictly evaluates higher-precedence operators first, before evaluating any operands of any less deeply nested part of the expression.

    That's the source of my confusion: I intuitively expected Perl to only use the operator precedence information to implicitly "add parenthesis" for disambiguation, but then evaluate the expression left-to-right, only recursing into nested sub-expression once they are encountered.

    That's two conceptually very different ways of defining evaluation order, but easy to miss because in practice it probably never makes a difference except in special cases involving += and friends.

    Well, almost never... :) Here's a demonstration of the evaluation order using tied scalars that report when they're being accessed:

    use warnings; use strict; package LoggingScalar { require Tie::Scalar; our @ISA = qw(Tie::StdScalar); sub FETCH { print "fetched: ".(${shift()} // '<undef>')."\n" } } tie my $x, 'LoggingScalar'; tie my $y, 'LoggingScalar'; tie my $z, 'LoggingScalar'; ($x, $y, $z) = qw(x y z); print "---\n"; my @a = ($x, $y . '!', $z);

    ...which outputs:

    --- fetched: y fetched: x fetched: z

    As for the mentioned perlop paragraph re. "undefined behavior", I suppose that refers to what Eily says here.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1077009]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2017-05-28 19:08 GMT
Find Nodes?
    Voting Booth?