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 //= "";