I just encountered a situation where and
and &&
behave differently with respect to warnings.
Here's the original script with and
.
#!/usr/bin/env perl
use strict;
use warnings 'FATAL' => qw[all];
my $var1;
my $var2;
my $defined = (defined $var1) and (defined $var2);
print ($defined ? "defined\n" : "undefined\n");
because first condition is false, the second expression in the and is never evaluated.
% perl defined.pl
Useless use of defined operator in void context at defined.pl line 8.
Exit 255
However if I change the operation to the higher-precedence but otherwise identical &&
, I don't get a void context warning.
#!/usr/bin/env perl
use strict;
use warnings 'FATAL' => qw[all];
my $var1;
my $var2;
my $defined = (defined $var1) && (defined $var2);
print ($defined ? "defined\n" : "undefined\n");
The program produces the expected result, "undefined\n"
.
% perl defined.pl
undefined
perldoc perlop
suggests that and
and &&
should be identical in all respects except for precedence, but does not explicitly state it.
As alternatives to && and || when used for control flow, Perl provides the and and or operators (see below). The short-circuit behavior is identical. The precedence of "and" and "or" is much lower, however, so that you can safely use them after a list operator without the need for parentheses:
The assignment operator has a higher precedence than and
, so
my $defined = (defined $foo) and (defined $bar);
is equivalent to
(my $defined = (defined $foo)) && (defined $bar);
You can see this with B::Deparse:
$ perl -MO=Deparse -e'my $defined = (defined $foo) && (defined $bar)'
my $defined = defined $foo && defined $bar;
-e syntax OK
$ perl -MO=Deparse -e'my $defined = (defined $foo) and (defined $bar)'
defined $bar if my $defined = defined $foo;
-e syntax OK
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With