Siaris

Logical Operators
27 Sep 01 - http://www.siaris.net/index.cgi/Programming/LanguageBits/Perl/20010927.rdoc

Perl has operators to perform logical OR/AND/NOT operations, and they come in two forms: a high precedence symbolic form: ||, &&, !, and a low precedence form: or, and, not (respectively).

Logical AND and OR are binary operators and are often used to combine expressions in a conditional statement:

    if ($value > 5 && $value < 10) {
        print "$value is between 5 and 10 exclusive\n";
    }

    if (lc($input) eq 'q' || lc($input) eq 'quit'){
        warn "Quitting application now\n";
        clean_up();
        exit;
    }

The NOT operator is a unary operator that returns the negated (opposite) truth value of its argument:

    if ( not $done ) {                  # also: if(!$done){
        print "We are not finished\n";
    }

Often we can use either the high or low precedence forms, however, occasionally precedence matters — consider the following mistaken expression and how the logical test is actually parsed:

    $a=0;
    $b=1;
    if (not $a && not $b) {
        print "\$a and \$b are false\n";
    }

The programmer wanted to test that both $a AND $b were false. If $a is false then not($a) would be true, and similarly for $b, but this expression obviously fails. That is because the precedence of && is much higher than the precedence of ‘not’ so the expression is actually parsed as:

    if ( not ($a && (not $b)) ) {

which is not what was intended. We could fix this in a few different ways: either use the lower precedence form of AND (‘and’), or the higher precedence form of ‘not’:

    if ( !$a && !$b) {

    if (not $a and not $b) {

A more interesting aspect of the logical AND and OR is that they short-circuit their second operand if they do not need to check it to determine the truth or falsity of the entire expression:

    $a = 0;
    $b = 1;
    if ($a and $b) { print "Both a and b are true\n" }

In the above situation, Perl knows that for the an AND operation to be true, both sides must be true — if the left side is false then Perl doesn’t bother checking the right side (it already knows the whole expression must be false). This short-circuit, or lazy evaluation comes in handy in various situations outside of conditional tests — one of which you should be familiar with:

    open(FILE, $file) or die "Can't open $file: $!";

The open() function returns a true value when it succeeds. Perl knows that only one expression must be true for an OR operation to succeed, so if the left expression is true Perl ignores the right hand side. In this case, that means the right hand side is only evaluated if the file could not be opened (in which case, the die() function is called).