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

It does, unless precedence or associativity gets in your way. Your example demonstrates this quite well:

Not at all. My example shows that precedence has no effect on the operatoroperand evaluation order.

And since associativity breaks ties in precedence, how could it possibly have any effect on the operatoroperand evaluation order if precedence doesn't.

Updated (18:55 EDT): I keep typing "operator" when I try to type "operand"! argh!

  • Comment on Re^3: Will "$_[0]=shift" always resolve shift first?

Replies are listed 'Best First'.
Re^4: Will "$_[0]=shift" always resolve shift first?
by tilly (Archbishop) on Sep 09, 2008 at 00:47 UTC
    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.

      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 }

      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.
Re^4: Will "$_[0]=shift" always resolve shift first?
by moritz (Cardinal) on Sep 08, 2008 at 22:28 UTC
    My example shows that precedence has no effect on the operator evaluation order.

    Not quite true. * is evaluated before +. (Which makes a difference for overloaded operators)

    And since associativity breaks ties in precedence, how could it possibly have any effect on the operator evaluation order if precedence doesn't.
    You're right here. After reading betterworld's comment I thought that the right associativity of the = operator was the key, but it isn't. It seems to be just a special case for =.
      Sorry for the confusion. I said "operator" where I meant "operand" earlier. I keep mistyping it. I corrected myself in time elsewhere, but missed that one. It's now fixed, so you may want to reread it.