Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

if modifier of a print statement

by si_lence (Deacon)
on Jun 30, 2009 at 10:44 UTC ( #775973=perlquestion: print w/replies, xml ) Need Help??
si_lence has asked for the wisdom of the Perl Monks concerning the following question:

I have a strange behavior I do not really understand. I want to print out some lines with processing and some other without.
What I did in the first place was something like this:
use strict; use warnings; my @test = qw(no_proc line_to_proc1 line_to_proc2); for (@test) { print $_ . "\n" && next if /no_proc/; #no processing print "$_ : in proc \n"; #processing }
this does not work, i.e it prints only the 'processing' lines.

So I changed the first print line to

print ($_ . "\n") && next if /no_proc/;
This gives the output I want, but also the note
print (...) interpreted as function at ...
So I ended up using an if statement
if (/no_proc/){ print $_ . "\n"; next; }
That works again without any notes, but still leaves me wondering if and how it could be done with a modifier if.
Any insight welcome.

Replies are listed 'Best First'.
Re: if modifier of a print statement
by davorg (Chancellor) on Jun 30, 2009 at 10:51 UTC
      davorg is right. This is a precedence issue.

      using 'and' instead of '&&' lowers the operator precedence.

      The first one is interpreted as:
      print $_ . ("\n" && next) if /no_proc/;

      The fixed one is intepreted as:
      (print $_ . "\n") and next if /no_proc/;

      Note that the brackets include the print statement, not just the parameters.
        The first one is interpreted as:
        print $_ . ("\n" && next) if /no_proc/;

        The  . operator has higher precedence than the  && operator so it is actually interpreted as:

        $ perl -MO=Deparse,-p -e' print $_ . "\n" && next if /no_proc/; ' (/no_proc/ and print((($_ . "\n") && next))); -e syntax OK
Re: if modifier of a print statement
by Marshall (Abbot) on Jun 30, 2009 at 11:30 UTC
    Yes, this is an op precedence problem. But why even confront that?
    my @test = qw(no_proc line_to_proc1 line_to_proc2); foreach (@test) { # this is actually just one line, indented to # make the if/else more clear. The trailing ";" # isn't even necessary. # this looks like a simple "we do either a or b, # but we will do one of them for sure situation, # ie if/else. The single statement below probably # equates to exactly the same machine code as a # more lengthy if/else statement. There is no # "next", there is no "and". /no_proc/ ? print "$_\n" : print "$_ : in proc\n" ; } __END__ prints: no_proc line_to_proc1 : in proc line_to_proc2 : in proc
      /no_proc/ ? print "$_\n" : print "$_ : in proc\n" ;

      You are using the Conditional Operator in void context.   That is usually written as:

      print /no_proc/ ? "$_\n" : "$_ : in proc\n";
        I think what I have is correct. It compiles and runs under "use strict;" and "use warnings;".

        The /no_proc/ is a match statementoperator on $_ which yields a true/false value. If the line in $_ has "no_proc", it gets printed and that's it. If that line doesn't have "no_proc" then the 2nd "else" statement is printed...."$ proc".

        print will return a "true value". What would "print /adsf/;" mean? I think nothing, but I've been wrong before!

        Updated: changed "statement" to "operator"

        You can only write it that way because both clauses in the expression happen to call the same function. If the statement was:
        /no_proc/ ? foo "$_\n" : bar "$_ : in proc\n";
        you could not have applied such a transformation, and the ?: would be left in void context.

        But I don't understand the fear of void context of particular functions or operators. Some people claim to get utterly confused when encountering a map in void context, breaking their tiny little brains on the question whether the author might have intended something else. You don't seem to like ?: in void context. But then you happily use print in void context, totally ignoring its return value.

        Me, I happily use anything in void context if that suits me. And I ain't afraid in the dark either.

Re: if modifier of a print statement
by jwkrahn (Monsignor) on Jun 30, 2009 at 12:21 UTC
    So I changed the first print line to

    print ($_ . "\n") && next if /no_proc/;

    This gives the output I want, but also the note

    print (...) interpreted as function at ...

    You get that warning message because of the space between print and the left parenthesis.   If you had written it as

    print($_ . "\n") && next if /no_proc/;

    you would not get a warning.

Re: if modifier of a print statement
by Anonymous Monk on Jun 30, 2009 at 11:57 UTC
    Thanks for the explanations. Really makes sense now.
    Cheers, si_lence

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://775973]
Approved by ELISHEVA
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2017-07-26 19:27 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (400 votes). Check out past polls.