简体   繁体   English

具有Undef的Perl三元运算符

[英]Perl Ternary Operator with Undef

I am having issues with getting a ternary operator to work using undef. 我遇到了让三元运算符使用undef工作的问题。 My original code that works: 我的原始代码有效:

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";
        }

I have some elseif as well, but didn't want to bog this all down. 我也有一些其他的,但不想让这一切陷入困境。 Everything works, and if Owner is undefined in my hash, then when it goes to print it is a blank spot as expected. 一切正常,如果在我的哈希中未定义所有者,那么当它打印时,它是预期的空白点。 So it prints like this: 所以打印像这样:

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 

I want to now make it so that $name is $emp->{Owner} unless Owner is undefined then instead of a blank spot it would say 'Undef.' 我想现在这样做,以便$ name是$ emp - > {Owner},除非Owner未定义,而不是空白点,它会说'Undef'。 So I wanted to change all the parts of my code that say $name = $emp->{Owner} to a ternary operation. 所以我想将我的代码的所有部分改为$ name = $ emp - > {Owner}到三元操作。

I have tried many different uses of the () with undef as that is what the error stated. 我尝试了使用undef的()的许多不同用途,因为这是错误说明的。 A couple of similar posts talked about the defined-or usage, which I tried, and other posts stated to use defined, but if I do, then all names become 'Undef' and not just the blank ones. 一些类似的帖子讨论了我尝试过的定义或用法,以及其他用过定义的帖子,但是如果我这样做,那么所有的名字都会成为'Undef',而不仅仅是空白名称。 Some of these do nothing and I still get blanks. 其中一些什么都不做,我仍然得到空白。 Others give errors where $a is now uninitialized. 其他人给出了$ 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';

Any help would be greatly appreciated. 任何帮助将不胜感激。 Thank you. 谢谢。

Owner=>''

Empty is not undefined, so 空未定义,所以

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

will always return $emp->{Owner} content, even if it's empty. 将始终返回$emp->{Owner}内容,即使它是空的。 However 然而

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

Will substitute 'Undef' if $a is empty and $emp->{Owner} if not, because $a is defined, but empty, ie 'False' 如果$a为空,将替换'Undef',如果没有,则替换$emp->{Owner} ,因为$a已定义,但为空,即'False'

upd: there is sort of an uglier form of a ternary operator. upd:有一种更丑陋的三元运算符形式。 it should be used only for fun, because it makes code quite a bit less readable: 它应该只用于娱乐,因为它使代码的可读性相当低:

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

The answer you want is: 你想要的答案是:

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

If $emp->{Owner} is not a false value (example: undefined, zero, empty string...) then it will be assigned. 如果$emp->{Owner}不是假值(例如:undefined,zero,空字符串......),那么它将被分配。 Otherwise, Perl will assign whatever is to the right of the operator. 否则,Perl将分配运营商右侧的任何内容。

Also, let me add that undef is a function that changes the argument to an undefined value and always returns an undefined value. 另外,让我补充一点, undef是一个将参数更改为未定义值并始终返回未定义值的函数。 For example, a very common mistake is to do something like this: 例如,一个非常常见的错误是做这样的事情:

if (undef $var) {
   # do something
}

This is not testing if $var is undefined. 如果$var未定义,则不测试。 Rather, it is making $var undefined and then testing the expression---which will be false-ish, so this if block will never be executed. 相反,它正在使$var未定义,然后测试表达式---这将是假的,所以这个if块永远不会被执行。

That's why defined is recommended instead: 这就是建议defined的原因:

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

This will test $var without changing it. 这将测试$var而不更改它。

However, as others have noted, your variable was not really undefined to begin with. 但是,正如其他人所指出的那样,您的变量开始时并未真正定义。

You need to test for defined , not undef . 你需要测试已defined ,而不是undef

assuming $a is undef , your last example should work: 假设$aundef ,你的最后一个例子应该有效:

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

However, maybe you need to test for an empty string as well. 但是,也许你需要测试一个空字符串。 undef is not the same as an empty string; undef与空字符串不同; if you want the same action for both, you'll need to test each condition explicitly. 如果你想为两者做同样的动作,你需要明确地测试每个条件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM