Wascally Perl Operators

I just finished writing a test that discovered I’d made a rather dumb and (upon looking back) rather obvious mistake in a return value in this Perl application I’m working on. The mistake involves a certain errant combination of return and and must be dealt with carefully.

The particular bit of code looks something like this:

sub blah {
    return $foo and $bar;
}

For those who don’t know Perl intimately, Perl has two “and” operators. One named “and” and the other named “&&” like C. These are not strict synonyms. They are both shortcut operators, but the “&&” and the “and” sit at very different places in the operator precedent order. In Perl “&&” has a relatively high precedent and “and” is very, very low.

Back to the problem: this return was returning true when $foo was true and $bar was false. After rereading this line I smacked my forehead and said, “Duh!” The problem is that “return” actually has a higher operator precedent than “and” so this is how Perl would break it out if it showed the AST with parenthesis:

sub blah {
    (return $foo) and ($bar);
}

This means the code immediately return $foo in all circumstances. I might as well have just written:

sub blah {
    return $foo;
}

The solution, then, is to either use the “&&” operator:

sub blah {
    return $foo && $bar;
}

Or use explicit parenthesis:

sub blah {
    return ($foo and $bar);
}

Or don’t use the “return” operator (since subroutines in Perl always return the value of the last expression executed):

sub blah {
    $foo and $bar;
}

Cheers.

About this Entry

This page contains a single entry by Andrew Sterling Hanenkamp published on June 2, 2009 10:34 PM.

Converting from iTunes to Banshee was the previous entry in this blog.

Weight Loss, My Way is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.