Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

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

by Eily (Curate)
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.


Comment on Re^3: Why does the first $c evaluate to the incremented value in [$c, $c += $_] ?
Select or Download Code
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?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1077009]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (8)
As of 2015-07-07 08:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (87 votes), past polls