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.