Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should you use '||' or lower precedence 'or' when reporting an error in Perl?

While reading the latest edition of The Camel Book I was struck by the following code fragment on p522:

use Fcntl ":flock";
eval {
    local $SIG{ALRM} = sub { die "alarm clock restart" };
    alarm 10;               # schedule alarm in 10 seconds
    eval {
        flock(FH, LOCK_EX)  # a blocking, exclusive lock
            || die "can't flock: $!";
    };
    alarm 0;                # cancel the alarm
};
alarm 0;               # race condition protection
die if $@ && $@ !~ /alarm clock restart/; # reraise

I had been taught that you should always use the low precedence logical OR operator 'or' in preference to the logical OR operator '||'.

Looking further in the book, I see plenty of other examples using the same logic.

Have the rules or levels of precedence changed?

Or is the handling of '||' and 'or' changed in later versions of Perl? (Unfortunately, we are welded to 5.6.1 atm due to legacy code).

like image 453
Rob Wells Avatar asked Feb 15 '13 10:02

Rob Wells


2 Answers

The precedence of || and or has not changed. Using || with die is a bit dangerous if you are not using parentheses around function attributes, consider

flock FH, LOCK_EX || die "can't flock: $!"; # WRONG!

That's why some people prefer or for control structures. With parentheses, there is no difference.

like image 119
choroba Avatar answered Nov 15 '22 18:11

choroba


[As a style question, this should probably be CW'ed. That said, I do have an opinion.]

The Camel is a terrible guide to style; that's not its job. The code it presents will be correct in that it does what it says on the tin, but turning its examples into something of actual use is mostly left as an exercise to the reader.

As for your particular question, prefer the English versions for logic and reserve the C-like versions for cases where you want a value. So:

if ($x or $y) { ... }
if (my $z = $x || $y) { ... }
$x or die "Ohnoes!"; # Though I prefer `die "Ohnoes!" unless $x;`
return 5 unless $x and $y;
return $x && $y; # Important!  `return $x and $y;` is really-really wrong

This'll see you through most code with a minimum of parenthesization.

like image 40
darch Avatar answered Nov 15 '22 20:11

darch