It seems comparison undef ne undef
returns undef. Does Perl have idiomatic way to convert it to perls "boolean"?
Also I find following to be strange:
undef ne undef || 0; # 0
(undef ne undef) || 0; # undef
Could you explain, please, what is happening?
It seems comparison
undef ne undef
returnsundef
.
It doesn't.
ne
returns either the special scalar true
(known as &PL_yes
internally) or the special scalar false
(&PL_no
), never undef
. In this particular case, it returns false
.
$ perl -e'
use v5.36;
use experimental qw( builtin );
use builtin qw( is_bool );
sub inspect {
!defined( $_[0] ) ? "[undef]" :
is_bool( $_[0] ) ? ( $_[0] ? "[true]" : "[false]" ) :
$_[0]
}
my $x = undef ne undef; # Line 12
say inspect( $x ); # [false]
'
Use of uninitialized value in string ne at -e line 12.
Use of uninitialized value in string ne at -e line 12.
[false]
(The results are the same in earlier versions of Perl, but is_bool
was only introduced in Perl v5.36.)
false
is a scalar that contains the integer zero, the float zero and the empty string.
$ perl -e'
use v5.36;
use experimental qw( builtin );
use builtin qw( false );
{ my $x = ""; say 0+$x; say "[$x]"; } # Line 6
say "--";
{ my $x = 0; say 0+$x; say "[$x]"; }
say "--";
{ my $x = false; say 0+$x; say "[$x]"; }
'
Argument "" isn't numeric in addition (+) at -e line 6.
0
[]
--
0
[0]
--
0
[]
I find following to be strange:
That's because it's not true. The two snippets are 100% equivalent, and they both return 0
.
$ perl -e'
use v5.36;
use experimental qw( builtin );
use builtin qw( is_bool );
sub inspect {
!defined( $_[0] ) ? "[undef]" :
is_bool( $_[0] ) ? ( $_[0] ? "[true]" : "[false]" ) :
$_[0]
}
{ my $x = undef ne undef || 0; say inspect( $x ); } # Line 12 # 0
{ my $x = ( undef ne undef ) || 0; say inspect( $x ); } # Line 13 # 0
'
Use of uninitialized value in string ne at -e line 12.
Use of uninitialized value in string ne at -e line 12.
0
Use of uninitialized value in string ne at -e line 13.
Use of uninitialized value in string ne at -e line 13.
0
(The results are the same in earlier versions of Perl, but is_bool
was only introduced in Perl v5.36.)
Could you explain, please, what is happening?
ne
is a string comparison operator. So it starts by casting its operands into strings. Converting undef
to a string produces the empty string, and emits a warnings. Since the empty string is equal to the empty string, ne
returns a false value, and specifically the special false
scalar.
Since false
is a false value, ||
evalutes and returns its right-hand side value (0
).
Does Perl have idiomatic way to convert it to perls "boolean"?
The simplest way to get true
or false
from a value is to negate it twice.
my $normalized = !!$x;
The simplest way to get 1
if true or 0
if false is to use the conditional operator.
my $normalized = $x ? 1 : 0;