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

Big-time newbie, so please don't laugh too hard...

In what order is a compound IF evaluated - right-to-left or left-to-right?

Does Perl immediately stop evaluating a compound IF once a false evaluation occurs?

I am building an IF statement of at least 10 comparisons and want it to evaluate as fast as possible.

A similar example:

if (($A ne "ONE") && ($B eq "TWO")) { ... } else { ... }

So, if the odds are that ($A ne "ONE") will fail more often, should I write:

if (($A ne "ONE") && ($B eq "TWO"))

-or- should I write:

if (($B eq "TWO") && ($A ne "ONE"))

Does it matter - does Perl care???

thanks...
-mike

Replies are listed 'Best First'.
Re: In what order is a compound IF evaluated?
by diotalevi (Canon) on Jul 09, 2004 at 22:03 UTC

    if() doesn't have an order but && does.

    From perlop

    if the left operand is false, the right operand is not even evaluated

Re: In what order is a compound IF evaluated?
by Old_Gray_Bear (Bishop) on Jul 09, 2004 at 22:32 UTC
    The notion you have here is 'short-circuiting' the evaluation. The 'if' evaluation works from the left and stops as soon as it determines that the final value does not depend on any of the clauses to the right. (One false with a string of and'd clauses is all you need. Ditto for one true and or'd clauses. It's the mixed logics that get you every the time....)
    if (($x eq 'c'}&&($y eq 'd')&&($z eq 'e')){ }
    If $x ='One', then the tests for $y and $z will be skipped, it does not matter what they are, the result is a big False. If you arrange the clauses in your compound 'if' in the order (roughly) of frequency, you will get the most speed out of it.

    That said, from a maintenance point of view, compound booleans are a pain to muck with unless the original author did something nice with the indentation. For example --

    if ( ($x eq 'a') && ($y eq 'b') && ($z eq 'c') ) { }
    I much prefer to cope with a switch statement or a cascade of if/elsif/else's when I have to trouble shoot some old code. It make the logic a bit clearer (to my mind), and makes adding another condition much easier.

    ----
    I Go Back to Sleep, Now.

    OGB

Re: In what order is a compound IF evaluated?
by shemp (Deacon) on Jul 09, 2004 at 22:08 UTC
    Perl evaluates left to right, but you need to be careful about operator precedence. (order of operations)

    Like in math: 5 + 7 * 3
    is evaluated as: 5 + (7*3) = 5 + 21 = 26
    Not: (5 + 7) * 3 = 12 * 3 = 36
    This is because multiplication has a higher precedence than addition, so sometimes you need parenthesis

    As for not evaluating a the expressions, it depends on the compound expression. For instance:
    my $x = 3; my $y = 5; # Case 1 if ( ($x > 1) || ($y > 10) ) {...} # Case 2 if ( ($x > 10) || ($y > 10) ) {...} # Case 3 if ( ($x > 10) && ($y > 10) ) {...} # Case 4 if ( ($x > 1) && ($y > 10) ) {...}
    Case 1 will stop after the first part because True OR <Anything> is true

    Case 2 will continue after the first part evals to false because False OR <Something> evals to True is the Something is true

    Case 3 will stop after the first part evals to false because False AND <Anything> is false.

    Case 4 will evaluate both parts because the first one is true, but True And False is False, so the second part needs to be evaluated.

    So it really depends on how the parts are joined. This is extensible to 3, 4, ..., N clauses too
      Perl evaluates left to right

      While it's certainly true that the short-circuit operators in Perl are left-to-right, which is what the OP mostly wanted to know at the moment, it might be saying to much to say that Perl evaluates left-to-right. It depends on your operators...

      print for map { $$_[0] } sort { lc $a->{name} cmp lc $b->{name} } grep { ref $_ } map { [$_, dblookup($_)] } <STDIN> unless grep { /--ignorestdin/ } @ARGV;

      Admittedly, the above is _somewhat_ atypical code.


      ;$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$;[-1]->();print
Re: In what order is a compound IF evaluated?
by runrig (Abbot) on Jul 09, 2004 at 23:00 UTC
    This is an easy thing to determine:
    sub true1 { print "true1\n"; 1; } sub true2 { print "true2\n"; 1; } sub false1 { print "false1\n"; 0; } sub false2 { print "false2\n"; 0; } if ( true1() && true2() ) { print "all true\n"; } if ( false1() || false2() ) { print "somethings wrong with the universe!\n"; } # Not tested but should output: true1 true2 all true false1 false2