在Perl中比较两个undef

l7wslrjt  于 2023-03-03  发布在  Perl
关注(0)|答案(2)|浏览(227)

看起来比较undef ne undef返回undef。Perl是否有惯用的方法将其转换为perls“布尔”?我还发现以下内容很奇怪:

undef ne undef || 0; # 0
(undef ne undef) || 0; # undef

你能解释一下发生了什么吗?

kqlmhetl

kqlmhetl1#

比较undef ne undef似乎返回undef
它没有。
ne返回特殊标量true(内部称为&PL_yes)或特殊标量false&PL_no),但不会返回undef。在此特定情况下,它返回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结果与Perl的早期版本相同,但is_bool仅在Perl v5.36中引入。)
false是包含整数零、浮点零和空字符串的标量。

$ 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
[]

我发现以下内容很奇怪:
因为这不是真的,这两个代码段是100%等价的,它们都返回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结果与Perl的早期版本相同,但is_bool仅在Perl v5.36中引入。)
你能解释一下发生了什么吗?
ne是一个字符串比较运算符。因此,它首先将其操作数转换为字符串。将undef转换为字符串将生成空字符串,并发出警告。由于空字符串等于空字符串,因此ne返回false值,特别是特殊的false标量。
由于false是一个false值,因此||计算并返回其右侧的值(0)。
Perl是否有惯用的方法将其转换为perls "boolean"?
从一个值获取truefalse的最简单方法是对它求反两次。

my $normalized = !!$x;

获取1(如果为真)或0(如果为假)的最简单方法是使用条件运算符。

my $normalized = $x ? 1 : 0;
6psbrbz9

6psbrbz92#

首先,undef ne undef不返回另一个undef。我想您可能有其他问题:

$ perl -lE 'say defined(undef ne undef) ? q(Defined) : q(Undefined)'
Defined

下面是一个更复杂的程序,它显示了Perl在引擎盖下面所查看的内容:

use Devel::Peek qw(Dump);
use v5.10;

my $null;
Dump($null);

my $result = undef ne undef // 17;
Dump($result);
say defined $result ? "Defined! <$result>" : "Not defined"

输出显示undef值与PL_no值不同(参见@ikegami的答案):

Defined! <>
SV = NULL(0x0) at 0x7f980f8163a0
  REFCNT = 1
  FLAGS = ()
SV = PVNV(0x7f980e8098b0) at 0x7f980f82d590
  REFCNT = 1
  FLAGS = (IOK,NOK,POK,IsCOW,pIOK,pNOK,pPOK)
  IV = 0
  NV = 0
  PV = 0x101e9cac5 "" [BOOL PL_No]
  CUR = 0
  LEN = 0

还要注意的是,$result中的值不是17,因为如果defined-或//的左手是undef,它就不是17,它只是false。

相关问题