Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

if and else

by abubacker (Pilgrim)
on Aug 18, 2009 at 04:54 UTC ( [id://789340]=perlquestion: print w/replies, xml ) Need Help??

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

Dear all,
when I run the following statement

print "TRUE" if ( 0 ) or die "FALSE" ;

Output : FALSE

but at the same time I ran this code
print "TRUE" if ( 0 ) or print "FALSE" ;

Output : TRUEFALSE
why it is happening like this I thought that "or" will work like an else part and also tell me how to use else part in this style

please help me out!

Replies are listed 'Best First'.
Re: if and else
by fullermd (Priest) on Aug 18, 2009 at 05:10 UTC

    Neither of those snippets is doing what you think it is. Look at what B::Deparse tells you.

    % perl -MO=Deparse -e 'print "TRUE" if ( 0 ) or die "FALSE"' print 'TRUE' if die 'FALSE'; % perl -MO=Deparse -e 'print "TRUE" if ( 0 ) or print "FALSE"' print 'TRUE' if print 'FALSE';

    Basically, Statement Modifiers are the last thing on a line, so your if ( 0 ) or die "FALSE" actually means if( (0) or die "FALSE"). And the return value of the die (or print) is what determines whether your initial print actually runs. Since print is returning something true, and die doesn't return, you end up with the results you saw.

Re: if and else
by tilly (Archbishop) on Aug 18, 2009 at 05:44 UTC
    The output of the second snippet is NOT what you say it is. It is "FALSETRUE". Which gives a hint to what happens. Which (as has already been said by another poster) is that you're evaluating (0) or print "FALSE" to decide whether to print "TRUE". And since printing "FALSE" is true, you're printing "TRUE" afterwards.

    Incidentally the built in trinary function does exactly what you are trying to do. The pattern for that looks like this:

    CONDITION ? do_if_true() : do_if_false();
    So your intended behavior can be seen from:
    0 ? print "TRUE" : print "FALSE";
    Or more concisely with:
    print( 0 ? "TRUE" : "FALSE" );
Re: if and else
by ikegami (Patriarch) on Aug 18, 2009 at 06:58 UTC

    "( 0 )" is the same as "0", and "0 or EXPR" is the same as just "EXPR".

    That means
    print "TRUE" if ( 0 ) or die "FALSE";
    is equivalent to
    print "TRUE" if die "FALSE";
    And since die doesn't return, the above is equivalent to just
    die "FALSE";

    That means
    print "TRUE" if ( 0 ) or print "FALSE";
    is equivalent to
    print "TRUE" if print "FALSE";
    which prints FALSE, and if successful, also prints TRUE.

    You seem to be under the impression that "print "TRUE" if ( 0 )" is an expression (rather than a statement) or that the operands of "or" can be statements. Neither is the case.

Re: if and else
by ELISHEVA (Prior) on Aug 18, 2009 at 07:31 UTC

    The differences you see come about because or takes precedence over if. Because of this, or doesn't act like "else". Instead it turns its neighbors into a single condition used by if. If you put in parenthesis to explicitly show precendence, the two statements you wrote above look like this:

    print "TRUE" if (0 or die "FALSE"); print "TRUE" if (0 or print "FALSE"); #or alternatively if (0 or die "FALSE") { print "TRUE"; } if (0 or print "FALSE") { print "TRUE"; }

    Once you see the precedence, the difference in behavior is obvious: when 0 or die "FALSE" gets evaluated it dies before ever getting to what is inside of if {...}. On the other hand, 0 or print "FALSE" evaluates to true and causes Perl to enter inside of the if {...} statement. Hence, "FALSETRUE" gets printed.

    Best, beth

Re: if and else
by biohisham (Priest) on Aug 18, 2009 at 07:22 UTC
    Try the following, it will give you true for all the evaluations.

    print "TRUE" if ( 1 ) or die "FALSE" ; print "TRUE" if ( 2 ) or die "FALSE" ; print "TRUE" if ( 3 ) or print "FALSE" ; print "TRUE" if ( 4 ) or print "FALSE" ;
    correlate this with the way Perl responds to return values of (undef, "" or 0) to indicate failure, together with what everybody here said you would notice that, in your code, when the if statement evaluates a 0 or a null return value the "print "TRUE" " statement would not be carried out..but when it evaluates 1 or the execution of another statement that has a return value(as in the second snippet of yours) it will be carried out and you would see "TRUE" printed

    Your code addresses a precedence issue as ELISHEVA clarified too (UPDATE)


    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
Re: if and else
by Boldra (Deacon) on Aug 18, 2009 at 14:43 UTC

    I think what you're asking is "how do I write a postfix if, with an else part?" The answer is a rare one in perl - "you can't".

    The following are some alternatives, all equivalent. I have replaced your if(0) with a $test variable which is true 50% of the time.

    use 5.010; #gives you 'say' my $test = rand > 0.5; # two postfix tests: say 'TRUE' if $test; say 'FALSE' if not $test; # a one-liner conventional if if($test) { say 'TRUE' } else { say 'FALSE' } # two lines, using 'and' and 'or': $test and say 'TRUE'; $test or say 'FALSE'; # a ternary (my favourite): say $test ? 'TRUE' : 'FALSE';


    - Boldra

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (7)
As of 2024-04-23 20:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found