Search code examples
perlcomma-operatororder-of-execution

Order of execution with comma operator in Perl


Consider the following script:

print'+'x$z,($z=1,$w)?'':$_ for 1..3;

This prints, as I would expect, 1+2+3. The variable $z is initially unassigned, so '+'x$z evaluates to empty; after that, $z is set to 1, so '+'x$z now evaluates to +.

However, if I change this so that $z contains the + itself:

print$z,($z='+',$w)?'':$_ for 1..3;

the script now prints +1+2+3. This seems to suggest to me that the order of execution is different, but I don’t understand why.

What are the precise rules regarding order of execution that cause these two examples to behave differently? Is the order of execution even well-defined?


Solution

  • Arguments are passed by reference in Perl.

    print $z, ($z='+',$w) ? '' : $_;
    

    is basically

    {
       local @_;
       alias $_[0] = $z;
       alias $_[1] = ($z='+',$w) ? '' : $_;
       &print;
    }
    

    Because $_[0] is aliased to $z, changes to $z are reflected in $_[0], even if those changes occur after the argument is evaluated.

    You can see the same effect in the following:

    my $x = 3;
    sub f { 
       ++$x;
       print("$_[0]\n");
    }
    f($x);  # 4