Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Unexpected parsing

by JadeNB (Chaplain)
on Dec 16, 2009 at 02:23 UTC ( #812985=perlquestion: print w/replies, xml ) Need Help??

JadeNB has asked for the wisdom of the Perl Monks concerning the following question:

After reading Conditional Operator, and delighting in the potential for unreadable code coming from using a conditional operator as an lvalue, I wondered how far in advance the lvalues have to be declared.

Huh? Well, we know that

my ( $c, $d ); 1 ? $c : $d = 'Hi';
is the same (to B::Deparse) as
my ( $c, $d ); $c = 'Hi';
but what if you don't want to declare the variables in advance? Well,
my $d; 1 ? my $c : $d = 'Hi';
is the same as
my $d; my $c = 'Hi';
In the other direction, here's a strict-safe program that B::Deparse makes non-strict-safe:
$ perl -MO=Deparse -e 'my $c; 1 ? $c : my $d; $d' my $c; $c; $d; -e syntax OK
*. How about if we declare both variables in the conditional?
$ perl -e '1 ? my $c : my $d' Invalid separator character '$' in attribute list at -e line 1, near " +$c : my " Execution of -e aborted due to compilation errors.
Now, maybe there's some reason that parsing : my $d as an attribute list is good, or at least expected; but I can't see why 1 ? my $c : my $d would be parsed that way, but 1 ? my $c : $d wouldn't. Would somemonk enlighten me?

UPDATE: * Notice that B::Deparse changes the semantics here (but I guess there's always the disclaimer that that might happen). For example,

our $d = 'Out'; { 1 ? 0 : my $d; $d = 'In'; } say $d;
prints Out, but is converted by B::Deparse into
our $d = 'Out'; { '???'; $d = 'In'; } say $d;
which prints In.

UPDATE: Oh, maybe it's that a colon followed by whitespace and an alphanumeric is always interpreted as the beginning of an attribute list, even if we're waiting for the interstitial colon of a conditional operator. Is this correct? If so, is it the desired behaviour? If so, should the precedence table in perlop be changed to reflect it?

Replies are listed 'Best First'.
Re: Unexpected parsing
by ikegami (Pope) on Dec 16, 2009 at 03:18 UTC

    and delighting in the potential for unreadable code coming from using a conditional operator as an lvalue

    It takes next to nothing to make the cond op unreadable, but using it as an lvalue itself doesn't make it unreadable.

    ($axis ? $x : $y) += $distance;

    I can't see why 1 ? my $c : my $d would be parsed that way, but 1 ? my $c : $d wouldn't.

    It appears to be another case where heuristics enter into play.

    my is a valid attribute name, so : my is presumed to be an attribute.

    $d is not a valid attribute name, so : $d is taken to be the else expression of the conditional.

    Untested, but parens should clear that up.

    1 ? (my $c : shared) : ... # shared is an attribute -vs- 1 ? (my $c) : shared # shared is func call

    perl -MO=Deparse -e 'my $c; 1 ? $c : my $d; $d'

    Note that conditionally executing my officially results in undefined behaviour.

      my is a valid attribute name, so : my is presumed to be an attribute.

      $d is not a valid attribute name, so : $d is taken to be the else expression of the conditional.

      Thanks for the explanation! (I eventually figured out that it must be something like that, and updated my post; but probably it was after you had already begun yours.)

      Since the word ‘attribute’ does not occur in perlop or perlsyn, and since no other punctuation mark requires a visit to perlfunc to figure out how it parses, I wonder if it might be appropriate for the precedence table to mention this unexpected (by me) interaction?

      Note that conditionally executing my is officially undefined behaviour.

      Good to know, thanks. Is there any unified list of officially undefined things? I know, for example, by luck, that $i++ + ++$i can officially do whatever it wants, but I had no idea about this; who knows what other corner cases I'm missing?

        I wonder if it might be appropriate for the precedence table to mention this unexpected (by me) interaction?
        No, I don't think so. The ':' isn't an operator, so it has nothing to do with precedence. It doesn't belong in a precedence table. Determining whether something is an operator (or part of an operator) or not isn't dealt with with the operator precedence table.
        Since the word ‘attribute’ does not occur in perlop or perlsyn, and since no other punctuation mark requires a visit to perlfunc to figure out how it parses
        But you only find something about attributes in perlfunc because my was specially added to perlfunc; my isn't a function. The details are in perlsub, where you would also go for punctuation as prototypes and some cases of parenthesis.
        Is there any unified list of officially undefined things?
        Not that I know of. But by all means, feel free to write up a list and submit is as a patch. Writing documentation doesn't require any coding language, which means most people can do it.

        Is there any unified list of officially undefined things?

        That's the only one that comes to mind. It's documented (too specifically) in perlsyn under statement modifiers (my ... if ...;).

        I know, for example, by luck, that $i++ + ++$i can officially do whatever it wants

        That one's simply undocumented.

        I wonder if it might be appropriate for the precedence table to mention this unexpected (by me) interaction?

        I don't see why not, although I don't think it'll ever be an issue in legit code (but my brain is too slow to make sure of that right now). Maybe as a warning in the doc for the cond op.

Re: Unexpected parsing
by BrowserUk (Pope) on Dec 16, 2009 at 02:35 UTC

    This is fine:

    c:\test>perl -MO=Deparse -e "my $c; 1 ? $c : my( $d ); $d" my $c; $c; $d; -e syntax OK

    In your version, it's trying to parse an attribute--like $c :shared


    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.
      In your version, it's trying to parse an attribute--like $c :shared
      I figured out from the error message what was happening with the parsing, but couldn't tell what was different about the 2 cases involving my $c that made them parse differently. I have updated my post with a guess (that it's the whitespace-plus-alphanumeric after the colon), but I'm not sure whether this is the desired behaviour or a bug (or my guess is wrong!).

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://812985]
Approved by moritz
Front-paged by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (6)
As of 2020-03-30 17:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    To "Disagree to disagree" means to:









    Results (175 votes). Check out past polls.

    Notices?