in reply to Extract potentially quoted words

Actually, what I learned from this is another lesson in precedence. I would've thought to write it as:
push @elements, $1 while /\G\s*"(.*?)"/gc || /\G\s*'(.*?)'/gc || /\G\s*(\S+)/gc;
I usually treat or as lower precedence than anything -- I use it almost exclusively as do_something() or die "Help!" After going through the perlop and perlsyn man pages, I think I see now: the ors are part of the expression that follows the while modifier, not part of the full expression.

Sooo.... In this case, the || works like the or. You could make an "or die" type of thing by parenthesizing the while expression:

push @elements, $1 while (/\G\s*"(.*?)"/gc or /\G\s*'(.*?)'/gc or /\G\s*(\S+)/gc) or die "Argh";
Although this is stupid since the while will return a false value at some point (you hope!), so you'll always die. But if you changed it to an and, you could detect if the loop never executed. (Hmmm... Potentially useful trick.)

Replies are listed 'Best First'.
Re: Re: Extract potentially quoted words
by tye (Sage) on Jun 07, 2001 at 00:25 UTC

    Although in Perl, most statements can also be used as expressions, there are a few exceptions. The while above is a statement modifier and cannot be used in an expression.

    For example:

    push @elements, $1 while (/\G\s*"(.*?)"/gc or /\G\s*'(.*?)'/gc or /\G\s*(\S+)/gc) or die "Argh";
    is still parsed as:
    push @elements, $1 while( (/\G\s*"(.*?)"/gc or /\G\s*'(.*?)'/gc or /\G\s*(\S+)/gc) or die "Argh" );
    and if we try to force your desired interpretation:
    (push @elements, $1 while /\G\s*"(.*?)"/gc or /\G\s*'(.*?)'/gc or /\G\s*(\S+)/gc) or die "Argh";
    we get: syntax error at line 1, near "$1  while"

            - tye (but my friends call me "Tye")
      No, there are no statements that can be used as expressions. What were you thinking? There's a clear delineation in Perl between statement things and expression things, and never the twain shall meet.

      -- Randal L. Schwartz, Perl hacker

        To quote perlsyn.pod:

        The only kind of simple statement is an expression evaluated for its side effects.

        Take a random Perl script you have lying about somewhere. Most of the statements in that code will likely be simple statments, that is, just an expression. Such statements can be used as expressions since they are, um, just "an expression evaluated for its side effects". You could put "my @value=" in front of it to demonstrate that fact and most of the time you end up with valid Perl code.

        There are lots of times where I take code that was a statement and rework code around such that I'm now using that statement as an expression (for example, by moving it into the condition of an if or while).

        But if you have a statement that isn't so simple, moving into a "context" where an expression is required will probably get you a syntax error.

                - tye (but my friends call me "Tye")
        Well, it was a misinterpretation. I guess when I read the line from perlsyn
        The only kind of simple statement is an expression evaluated for its side effects.
        I twisted it around to "a statement is an expression".

        But I think I've got it now: EXPR1 while EXPR2 is a statement, and using || versus or depends on (and affects) what else is in EXPR2, not the full statement.

        On the other hand, "do_something() or die" is an expression (which, being evaluated for its side-effects, is also a statement). If the do_something returns 0 or '', the die will be evaluated as part of the expression, not as a statement modifier.

        Have I got it right now?

        I guess I tripped on the outward similarity of the two, and thought of or as a statement modifier like while and if.

        P.S. merlyn, I don't think this is what you wanted to illustrate in your note, but I did learn something valuable. Thanks!

      Aha! I knew your last example wouldn't work because I tried it. But I misinterpreted how the code I posted was working.

      Thanks for the correction, I appreciate it.