Under what circumstances is “not” different from “if not”?
I used to think that unless
and are if not
completely equivalent, but this Q&A made me realize that they can lead to different conclusions in the context of a list
use strict;
use warnings;
use Data::Printer;
use feature 'say';
my %subs = (
unless => sub {
my ( $value ) = @_ ;
return "$value is a multiple of 3"
unless $value % 3 ;
},
if_not => sub {
my ( $value ) = @_ ;
return "$value is a multiple of 3"
if not $value % 3 ;
},
);
for my $name ( keys %subs ) {
my $sub = $subs{$name};
say $name;
my @results = map { $sub->($_) } 1 .. 10;
p @results;
}
Output
if_not
[
[0] "",
[1] "",
[2] "3 is a multiple of 3",
[3] "",
[4] "",
[5] "6 is a multiple of 3",
[6] "",
[7] "",
[8] "9 is a multiple of 3",
[9] ""
]
unless
[
[0] 1,
[1] 2,
[2] "3 is a multiple of 3",
[3] 1,
[4] 2,
[5] "6 is a multiple of 3",
[6] 1,
[7] 2,
[8] "9 is a multiple of 3",
[9] 1
]
In the above code snippet shows that unless
and if not
lead to the fact that the routine displays a different value of the last expression evaluated.
It seems that this is because he if not
considers him not
part EXPR
, while he unless
does not consider him part EXPR
.
Question
Are there any other code examples where the two are not synonymous?
source to share
The difference is that for your case unless
expression to the latest estimates $value % 3
, while for your event if not
expression with the last assessmentnot $value % 3
not
behaves like a simple operator, whereas if
and unless
are language constructs such as while
and for
that do not participate in the meaning of expressions
In any case, it is bad practice to rely on the return value of a subroutine if it has no return
path for every path or ends up with an expression. perldoc perlsub
talks about it
If not found
return
, and if the last statement is an expression, its value is returned. If the last statement is a loop control structure such asforeach
orwhile
, no return value is specified.
So, just because you think you know what a subroutine will evaluate without return
, it won't actually be reliable unless you end your subroutine with an expression and change it in later versions of Perl.
Just write return
your condition for a different case, and your code will become clearer. Or, you can use a conditional expression that specifies the return value for both conditions.
cond_exp => sub {
my ( $value ) = @_;
$value % 3 ? "" : "$value is a multiple of 3";
}
source to share