In article <[EMAIL PROTECTED]>,
        Amir Karger <[EMAIL PROTECTED]> writes:
> C:\>perl -e "$_='abcde';/./;print "$'",/../,$'
> cde1cde
>
> Is this another 5.6.1'ism (Looks like I'll have to upgrade to 5.8 for
> "@+" in any case) or was Jasper's solution using some slightly more
> mystical quoting?
>
> I'm still somewhat confused about exactly when objects (like searches
> or assignments) in a comma-separated lists, arguments to for, etc. get
> executed. Obviously this is important for Perlgolf, which so often does
> two or three things at a time. Rather than learn the rules, though, I
> usually just try all of the permutations I can think of. Which is
> probably one of many reasons I'm not actually winning these contests.

The perl evaluation is order is actually very straightforward, it's
exectly what you would naively expect from the precedence rules. The
surprise comes from the fact that what's pushed on the evaluation stack
(and the resultlist for list operators) are not the values, but
references to the values. And if a reference is shared, changes to the
referent will also change the values that still pending stuff referes to.

I'll give two extensive examples (hopefully we can use this as reference
if people wonder about this again).

Example:
 *  $a = 3;
    print ++$a + ++$a;

    - Start evaluating print (arguments)
      - Start evaluating +
        - Start evaluating the first ++$a
          - Increase $a to 4, return a reference to $a
        - Start evaluating the second ++$a
          - Increase $a to 5, return a reference to $a
        - Do the actual addition. Pending on the value stack are
          the two references to $a, fetch the values (each 5) and add (10)
          Return a reference to that 10
     - dereference all pending values (only a reference to 10 here), join them
       and print
     So this prints 10

 *   $a = 3;
     print $a, ++$a + 0 + ++$a, $a++

     - Start evaluating print (arguments)
       - Start evaluating the second "," (, is left associative)
         - Start evaluating the first ","
           - Start evaluating $a
             Return a reference to $a
           - Start evaluating the second + (+ is left assocaiative)
             - Start evalauting the first +
               - Start evaluating ++$a
                 - Increase $a to 4, return a reference to $a
               - Start evaluating 0
                 - Return a reference to 0
               - Do the addition. dereference the $a and 0 reference, add the
                 resulting 4 and 0 and return a reference to 4 (which is NOT
                 a reference to $a anymore !)
             - Start evaluation of the second $a++
               - Increase $a to 5, return a reference to it
             - Dereference the pending 4 and $a reference and add them,
               giving 9. Return a reference to that
           - Execute list context "," on the pending reference to $a and the
             reference to 9. This constructs a working list which still
             contains these 2 references (so NOT the values. so list ","
             is special in that after evaluation the values don't get
             dereferenced and evaluated, it just collects the value
             references).
         - Start evaluating the $a++
             put a reference to a copy of the value in $a (5) on the
             result stack, and increase $a to 6 (this is why the copy was
             needed, otherwise the result of $a++ would effectively be
             the value AFTER increment, so the same as $a++)
         - Make a new working list, now containing a reference to $a, a
           reference to 9 and a reference to 5
       - Dereference and join them, giving 695
     - output "695"

     A quite interesting result since the first 6 is the last value of $a,
     while the last 5 is the previous value of $a

So you see that the fact that perl acts on references which will still
pick up later changes explains the seemingly weird "back in history"
results perl can give.

Reply via email to