Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 为什么要评估“定义的$x&&$布尔上下文中的x?_Perl_Operators_Boolean - Fatal编程技术网

Perl 为什么要评估“定义的$x&&$布尔上下文中的x?

Perl 为什么要评估“定义的$x&&$布尔上下文中的x?,perl,operators,boolean,Perl,Operators,Boolean,为什么开发人员在几乎相同的条件下使用&& &&是一个“逻辑短路”运算符。首先,他正在测试$item->{targ_type}的定义性。如果且仅当定义了它(即&&的左侧为真),则他测试$item->{target\u type}是否包含真值。如果这两个条件都为真,则$target\u type(以及以后的$target\u id)会被分配到$item->{target\u type}或$item->{target\u id}中的值。如果其中一个条件为false,则分配一个空字符串 更新:试图读懂提

为什么开发人员在几乎相同的条件下使用
&&

&&
是一个“逻辑短路”运算符。首先,他正在测试
$item->{targ_type}
的定义性。如果且仅当定义了它(即
&&
的左侧为真),则他测试
$item->{target\u type}
是否包含真值。如果这两个条件都为真,则
$target\u type
(以及以后的
$target\u id
)会被分配到
$item->{target\u type}
$item->{target\u id}
中的值。如果其中一个条件为false,则分配一个空字符串


更新:试图读懂提出这个结构的程序员的想法:也许代码是以某种方式演变而来的,而程序员并没有花足够长的时间去思考它,从而认识到它是不必要的。也许程序员对定义性、真值、假值以及Perl中哪些类型的值是“假”之间的区别不确定。

这不是相同的条件

首先,他测试定义

my $target_type = (defined($item->{target_type}) && $item->{target_type}) 
                ? $item->{target_type} 
                : "";

my $target_id   = (defined($item->{target_id}) && $item->{target_id})
                ? $item->{target_id} 
                : "";
当使用未定义的值进行操作时,某些操作毫无意义

在第二种情况下,他测试真值或假值

defined($item->{target_type})
但是,由于
undef
是一个假值,因此第二个测试涵盖了这两种情况

在某些情况下,类似的模式是必要的,例如,在对照参考内容进行测试时

$item->{target_type}

很明显,他是那种带吊带的人
(已定义($x)和&$x)
几乎等同于
$x
,因为
undef
为false。(区别在于,如果
$x
undef
,那么
(defined($x)和&$x)
将是Perl的特殊假值,这是已定义的,但在本例中没有区别。)可能以前存在不同的条件(如
$x>0
)而
定义的
测试对于避免未初始化值的警告是必要的。然后有人删除了该条件,并没有考虑删除现在不必要的
定义的


使用
(已定义($x)和&$x)
(as)的另一个原因是向未来的维护程序员强调,
$x
可能没有定义。就我个人而言,我会使用注释,但是。

尽管&&的右侧可以自己使用,但我已经多次看到这种用法作为人类读者的语义提示,
$item->{target\u type}
可能没有定义


因此,即使可以删除LHS并保持类似的行为,维护人员也很容易误认为没有必要检查是否定义了值。(除非在一个紧密的循环中,额外评估的成本可以忽略不计,甚至在一个循环中,它也可能通过解释器中的优化来消除)。

回答你的问题需要读心术,但以下是一些按概率排序的原因:

  • 作者不是Perl程序员,因此对
    undef
    的真实性感到不安,
    定义的undef&&undef
    的计算结果为
    ,并使表达式的其余部分无效,或者两者都无效
  • 代码已经看到了一个修订,它删除了一些需要
    定义的
    测试才能正常工作的内容,例如
    定义的$x&&$xne'
    定义的
    测试是该编辑留下的粗糙部分,对维护人员来说是负值
  • 作者希望强调的是,该元素可能是
    undef
    ,因此对其进行了明确的测试。有更好的方法可以做到这一点,这些方法不会让未来的读者猜测其意图。比如说,评论
  • 如果定义了,
    $item->{target_type}
    可能包含一个具有重载布尔转换的对象,该转换的计算代价很高,并且您看到的是一个自我失败的微观优化。这种情况极不可能发生。不过很有趣

  • 非常简短的回答:这是为了避免在较旧的PERL中出现“使用未初始化值”警告,并在这种情况下指定默认定义的值。在v5.10及更高版本中,您将使用定义的or运算符:

    my $ref1 = "true";
    my $ref2 = \("true");
    
    if (ref $ref1 eq 'SCALAR' and $$ref1) {
      # This does not get executed
    }
    if (ref $ref2 eq 'SCALAR' and $$ref2) {
      # This does get executed
    }
    

    虽然答案中的单词是正确的,但我看不出它们回答了这个问题。另一种可能性是,原始编码者(错误地)认为
    if$item->{target_type}
    将使键变得生动。实际上
    defined unde&&unde
    的计算结果是Perl的规范假值,这是一个特殊的空字符串,在数字上下文中计算为0,而没有关于正常空字符串将给出的非数字值的警告。@cjm:True,尽管我要冒一个险说,原始作者不确定如果在数字上下文中使用
    $target\u type
    ,他是否会收到警告。我明白了,我现在明白了,我所在的公司仍在使用Perl 5.8,代码非常陈旧。
     $scalar //= "";