带有 Undef 的 Perl 三元运算符

Perl Ternary Operator with Undef

我在使用 undef 让三元运算符工作时遇到问题。 我的原始代码有效:

my $qr = [
    {IP=>'x.x.x.51',Testnet=>'bos-portal-legacy',Owner=>'Amund', Email => 'bosemail'},
    {IP=>'x.x.x.52',Testnet=>'bos-portal-2',Owner=>'Amund', Email => 'boemail2'},
    {IP=>'x.x.x.53',Testnet=>'bos-portal-legacy',Owner=>'Amund', Email => 'bosemail'},
    {IP=>'x.x.x.54',Testnet=>'sqa',Owner=>'Richard', Email => 'sqaemail'},
    {IP=>'x.x.x.55',Testnet=>'sqa',Owner=>'Richard', Email => 'sqaemail'},
    {IP=>'x.x.x.56',Testnet=>'fll-pro',Owner=>'Larry', Email => 'fllemail'},
    {IP=>'x.x.x.57',Testnet=>'fll-pro', Owner=>'', Email => 'fllemail'},
    {IP=>'x.x.x.58',Testnet=>'fll-pro2', Owner=>'', Email => 'flemail2'},
];
my $len = scalar @$qr;
print "Starting of array: $len\n";
my $l = $len;
my $a = @$qr[0]->{Owner};
func ($a);
my @ip;
my %test;
my $name;
my $manager;
my $ip_ref;
my $test_ref;
sub func{
foreach my $emp (@$qr) {
        if ($l > 1 && $emp->{Owner} eq $a) {
            $name = $emp->{Owner};   #to use with email as $a will change as cycle thru
            $manager = $emp->{Manager};
            push (@ip, $emp->{IP});                  #capture all IPs related to owner $name
            $test{$emp->{Testnet}} = $emp->{Email};              #capture unique testnets only related to owner $name
            $l--;                                    #to cycle thru array until reach last row
            print "Finished line: $l\n";
        }

我也有一些 elseif,但不想拖延这一切。一切正常,如果 Owner 在我的哈希中未定义,那么当它打印时它是预期的空白点。所以它打印成这样:

Starting of array: 8
Finished line: 7
Finished line: 6
Finished line: 5
Amund
x.x.x.51, x.x.x.52, x.x.x.53
bos-portal-2 
bos-portal-legacy 
Finished with Amund
Moving on to Richard: 4
Finished line: 3
Richard
x.x.x.54, x.x.x.55
sqa 
Finished with Richard
Moving on to Larry: 2
Larry
x.x.x.56
fll-pro 
Finished with Larry
Moving on to : 1
                     #Blank Spot want to have $name printed as 'Undef' instead
x.x.x.57, x.x.x.58
fll-pro 
fll-pro2 

我现在想使 $name 为 $emp->{Owner} 除非 Owner 未定义然后它会显示 'Undef.' 而不是空白点所以我想更改所有部分我的代码说 $name = $emp->{Owner} 进行三元运算。

我已经尝试了 () 和 undef 的许多不同用法,因为这就是错误所指出的。一些类似的帖子讨论了 defined-or 用法,我尝试过,其他帖子声明使用 defined,但如果我这样做,那么所有名称都会变成 'Undef' 而不仅仅是空白的。其中一些什么都不做,我仍然空白。其他人给出 $a 现在未初始化的错误。

$a = undef ? $name = 'Undefined' : $name = $emp->{Owner};
($a = undef) ? $name = 'Undefined' : $name = $emp->{Owner};
$a = undef($a) ? $name = 'Undefined' : $name = $emp->{Owner};
$name = undef($a) ? 'Undefined' : $emp->{Owner};
$name = $emp->{Owner} // 'Undefined';
defined($a) ? $name = $emp->{Owner} : $name = 'Undef';
$name = defined($a) ? $emp->{Owner} : 'Undef';

如有任何帮助,我们将不胜感激。谢谢。

你想要的答案是:

$name = $emp->{Owner} || 'No name provided';

如果 $emp->{Owner} 不是假值(例如:未定义、零、空字符串...),那么它将被赋值。否则,Perl 将分配运算符右侧的任何内容。

此外,让我补充一点,undef 是一个将参数更改为未定义值且始终 returns 未定义值的函数。例如,一个非常常见的错误是做这样的事情:

if (undef $var) {
   # do something
}

这不是在测试 $var 是否未定义。相反,它使 $var 未定义,然后测试表达式——这将是假的,所以这个 if 块将永远不会被执行。

这就是为什么建议 defined 的原因:

if (!defined $var) {
  # do something
}

这将在不更改的情况下测试 $var

但是,正如其他人所指出的,您的变量并不是真正未定义的。

Owner=>''

空不是未定义,所以

$name = defined($a) ? $emp->{Owner} : 'Undef';

将始终 return $emp->{Owner} 内容,即使它是空的。不过

$name = $a ? $emp->{Owner} : 'Undef';
如果 $a 为空,

将替换为 'Undef',否则将替换为 $emp->{Owner},因为 $a 已定义,但为空,即 'False'

upd: 三元运算符有一种更丑陋的形式。它应该只是为了好玩而使用,因为它会使代码的可读性大大降低:

$name =  $a && $emp->{Owner} || 'Undef';

您需要测试 defined,而不是 undef

假设 $aundef,你的最后一个例子应该有效:

$name = defined($a) ? $emp->{Owner} : 'Undef';

但是,您可能还需要测试空字符串。 undef 与空字符串不同;如果您想对两者执行相同的操作,则需要明确测试每个条件。