http://qs321.pair.com?node_id=941967


in reply to Re^2: Strange Regex Behavior
in thread Strange Regex Behavior

AFAIK, the order in which these subexpressions are evaluated is not defined. Adding one more operation (more or less any operation, "" or - or sqrt all work) does change the order of evaluation. But in the absence of some rule requiring the second and third operands of ?: to be evaluated after the first one rather than before, that's merely a detail of the implementation. I don't see any rule about it offhand in "conditional operator" in perlop.

Replies are listed 'Best First'.
Re^4: Strange Regex Behavior
by BrowserUk (Patriarch) on Dec 06, 2011 at 07:25 UTC

    Hm. I believe the fact that the entire ternary expression is wrapped in parens means that the contents of those parens must be evaluated before anything outside them per perlop:

    A TERM has the highest precedence in Perl. They include variables, quote and quote-like operators, any expression in parentheses, and any function whose arguments are parenthesized.

    I also believe that as the two ternary expressions are part of a (4-term) comma separated list, those four terms should be evaluated in strictly left to right order per perlop:

    "In list context, it's just the list argument separator, and inserts both its arguments into the list. These arguments are also evaluated from left to right."
    .

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    The start of some sanity?

      Ah... yes. That would make it a bug. Sorry.

      It doesn't seem to be the ternary operator causing the havoc, or pattern matching though:

      $,=", "; my $i; print $i++, $i, $i++, $i, $i++, $i;

      prints

      0, 3, 1, 3, 2, 3

      Using Dump, we can see that the optimizer is assuming that $1 must be constant for the length of time it takes to evaluate the list:

      use Data::Dump::Streamer; my $i; print Dump \($i++, $i, $i++, $i, $i++, $i);

      prints

      $SCALAR1 = \do { my $v = 0 }; $SCALAR2 = \do { my $v = 3 }; $SCALAR3 = \do { my $v = 1 }; $SCALAR4 = $SCALAR2; $SCALAR5 = \do { my $v = 2 }; $SCALAR6 = $SCALAR2;

      The autoincrement is also not a necessary ingredient:

      use Data::Dump::Streamer; print Dump \("x"=~/(x)/, $1, "y"=~/(y)/, $1, "z"=~/(z)/, $1);

      prints

      $SCALAR1 = \do { my $v = 'x' }; $SCALAR2 = \do { my $v = 'z' }; $SCALAR3 = \do { my $v = 'y' }; $SCALAR4 = $SCALAR2; $SCALAR5 = \do { my $v = 'z' }; $SCALAR6 = $SCALAR2;