in reply to Re^3: Will "$_[0]=shift" always resolve shift first?
in thread Will "$_[0]=shift" always resolve shift first?

Sorry, but not entirely true. If you remove precedence, then things get evaluated in a different order:
foo() + bar() + baz() 1 2 3 4 5
The following script proves this:
#! /usr/bin/perl use strict; package Foo; use overload '+' => sub { my ($self, $other) = @_; print "Evaluating $self + $other\n"; return Foo->new($$self + $$other); }, '0+' => sub {my $self = shift; $$self}, '""' => sub {my $self = shift; $$self}; sub new { my $class = shift; my $obj = \shift; print "Creating $$obj\n"; bless $obj, $class; } package main; Foo->new(1) + Foo->new(2) + Foo->new(4); __END__ Creating 1 Creating 2 Evaluating 1 + 2 Creating 3 Creating 4 Evaluating 3 + 4 Creating 7
That said, it looks like Perl likes to evaluate binary operations by evaluating the left hand side, then the right hand side, then performing the operation. (As you found, = is an exception.) With that order, the fundamental operands will generally go left to right. The order of the intermediate operations can generally be predicted fairly easily from perlop.

That said there are some points of precedence that are officially not documented. But that's because it is easier to say it is not documented than it is to explain why

my $foo = 0; print ++$foo + $foo++;
prints 3. (At least with Perl 5.8.)

The reason is that you evaluate the pre-increment that turns $foo into 1 then return $foo. You copy the existing value into a temp, then increment $foo again. You then add $foo (now 2) to its old value (1) to get 3. While there is no need to change this, anyone who depends on it deserves the worst of what they might get at some future date.

Replies are listed 'Best First'.
Re^5: Will "$_[0]=shift" always resolve shift first?
by ikegami (Patriarch) on Sep 09, 2008 at 02:03 UTC

    my $foo = 0; print ++$foo + $foo++; prints 3

    Treating + as a function is the best way I've found to explain it.

    do { local @_; alias $_[0] = ++$foo; # aliases to $foo alias $_[1] = $foo++; # aliases to anon 1 &sum # 2+1 }
Re^5: Will "$_[0]=shift" always resolve shift first?
by ikegami (Patriarch) on Sep 09, 2008 at 00:54 UTC

    Sorry, but not entirely true. If you remove precedence, then things get evaluated in a different order:

    eh? The operands are evaluated in the same order as before (foo then bar then baz). I've said all along precedence wasn't relevant to operand evaluation order, so what is "not entirely true"?

      There may be a bit of language confusion here. Mathematically the return of (foo() + bar()) is as much an operand as foo() and bar() are. Those intermediate operands get evaluated in different orders in our two examples.
        Ah! good point.