The joys of precidence
Precidence in Perl can catch you out.... it caught me out!
I have a script which emails some results to a subscriber on a daily basis. If there are no results, then it doesn't email the user - you only get an email if there's something to see, in other words.
As a reminder, the script will email a subscription-reminder to the user on the 1st of the month..... but only if they haven't been sent a results email that day.
The code went something like this:
my $has_emailed = email($recipient, $data);
my @t = localtime;
if ( not $has_emailed && not $t[3] ) {
my $text = get_reminder_message();
email( $recipient, $text);
}
The problem was that this was emailing a reminder every day!
Why? Precidence.
The &&
is a "short-circuiting and", and has a higher precedence that the not
. This means that the statement actually reads as:
if ( not ($has_emailed && not $t[3]) )
so following the logic, we get:
-
$t[3]
is the day-of-the-month, starting at 0 - FALSE for the 1st, and TRUE for every other day -
not $t[3]
is therefore TRUE on the 1st, and FALSE every other day -
$has_emailed
is TRUE if results were went to a user, FALSE if not.... we're assuming FALSE here -
($has_emailed && not $t[3])
is therefore FALSE -
not ($has_emailed && not $t[3])
becomes true.
There are a number of solutions:
if ( (not $has_emailed) && (not $t[3]) ) {...} # Be explicit where the not's go
if ( !$has_emailed && !$t[3] ) {...} # ! has a higher precedence that &&
if ( $has_emailed || $t[3] ) {} else {...} # cast the problem into the negative
unless ( $has_emailed || not$t[3] )) {...} # Perl::Critic doesn't like unless
Written by Ian Stuart
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Perl
Authors
janosgyerik
25.16K
Jean-Remy Duboc
12.25K
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#