Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Surprising Precedence/Context

by williams (Beadle)
on Jun 02, 2017 at 17:49 UTC ( [id://1191992]=perlquestion: print w/replies, xml ) Need Help??

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

I don't understand why the following dies on the last line.

#!/usr/bin/perl use strict; use warnings; my($bad)='/this/path/does/not/exist'; die "$bad exists, but must not\n" if -f $bad; my($yes1)=(defined $bad and -f $bad); #2nd parens seem unnecessary, die "yes1=$yes1\n" if $yes1; #but does not die here; good my($yes2)=defined $bad and -f $bad; #2nd parens removed, die "yes2=$yes2\n" if $yes2; #but dies here; why?

The parentheses on the left-hand side of the my statement for both $yes1 and $yes2 should impose list context on the right-hand side. So I'd expect the parentheses added for $yes1 to have no effect. Also, I didn't think the two operators used here, defined and -f, changed behavior between scalar and list context. Also, I'd expect the low-precedence and to keep the defined and the -f separated from each other.

This is on Linux with Perl 5.10.1, which I can't control. Thanks.

Jim

Replies are listed 'Best First'.
Re: Surprising Precedence/Context
by Paladin (Vicar) on Jun 02, 2017 at 18:03 UTC
    As you can see below, the = binds tighter than the and, so your second example is parsing as:
    (my($yes2)=defined $bad) and -f $bad;
    Deparse:
    [~]$ perl -MO=Deparse -e 'my($yes2) = defined $bad and -f $bad;' -f $bad if my($yes2) = defined $bad; -e syntax OK
      When looking at precedence issues, the -p (full parens) Deparse option is helpful.
      > perl -MO=Deparse,-p -e 'my($yes2) = defined $bad and -f $bad;' ((my($yes2) = defined($bad)) and (-f $bad));

      Ouch. Thanks.

      Jim

Re: Surprising Precedence/Context
by LanX (Saint) on Jun 02, 2017 at 19:15 UTC
    As a side note: Perl comes with with a second set of logical operators for and , or and not', with much higher  precedence  ie '&& , || and ! (compare perlop#Operator-Precedence-and-Associativity and perlop#Logical-Not ff)

    You wouldn't need parens then.

    One reason and and or are so weak is to allow their use in flow control (in combination with short circuiting)

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

      That must explain this too,

      #!/usr/bin/perl use strict; use warnings; sub returnsTrueButExpectedFalse {return 1 and 0} die if 1 and 0; #does not die, but die if returnsTrueButExpectedFalse(); #does die here, surprisingly

      B::Deparse shows the return statement as this,

      (return(1) and 0);

      which isn't quite enough to say the return(1) happens before the 0 is evaluated. That must be what's happening though, from your reminder about flow control and and.

      Thanks for the tip about B::Deparse.

      Jim

        like AnoMonk explained, use the -p switch with B::Deparse to see more parens

        D:\Users\lanx>perl -MO=Deparse,-p -e"sub { return 1 and 0 }" sub { ((return 1) and 0); } ; -e syntax OK

        Please note that -x7 or higher will also show the equivalence between if and and (albeit in the opposite direction)

        D:\Users\lanx>perl -MO=Deparse,-p,-x7 -e"sub { 0 if return 1 }" sub { ((return 1) and 0); } ; -e syntax OK

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!

A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (4)
As of 2024-04-25 07:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found