在Perl中 - 如果需要,可以禁用短路评估吗?

时间:2013-06-18 20:48:54

标签: perl optimization logic

这是this one的后续问题。

例如,假设我有三个程序需要运行,无论如何,如果所有程序都返回1则退出。

while (&proc1 && &proc2 && &proc3);

因为Perl正在使用短路评估,代码可能会也可能不会执行subs& proc2和& proc3,具体取决于前面的操作数(如果操作数为false,则不会执行以下操作数;更多信息{{ 3}}和here)。如果需要,有没有办法关闭此功能?

4 个答案:

答案 0 :(得分:8)

您可以只评估临时变量的每个子句,然后评估整个表达式。例如,为避免短路评估:

if ($x < 10 and $y < 100) { do_something(); }

写:

$first_requirement = ($x < 10);
$second_requirement = ($y < 100);
if ($first_requirement and $second_requirement) { do_something(); }

将评估两个条件。据推测,您需要更复杂的副作用条件,否则如果第一个条件为假,则没有理由评估第二个条件。

答案 1 :(得分:5)

你可以写

until ( grep !$_, proc1(), proc2(), proc3() ) {
  ...
}

无论你做什么,都不应该使用&符号语法调用子例程,例如&proc1。多年来这一直是错误的,取而代之的是proc1()

答案 2 :(得分:3)

您可以使用乘法运算符

while (&proc1 * &proc2 * &proc3) { ... }

这将评估所有三个操作数,如果其中任何一个为假(零),则评估为false。

如果您担心有关未初始化值的警告,可以使用按位 - 并使用!! cast-to-boolean伪运算符:

while (!!&proc1 & !!&proc2 & !!&proc3) { ... }

这几乎可以做同样的事情。 cast-to-boolean是必要的,因为按位和两个任意真值的结果可能仍然是假的(例如,1 & 2计算为0)。

答案 3 :(得分:1)

我不知道有什么方法可以禁用短路评估,但是你可以在循环体的开头评估每个组件,如果任何条件都是假的话就中断。

while (1) {
    my $result1 = &proc1;
    my $result2 = &proc2;
    my $result3 = &proc3;
    last unless ($result1 && $result2 && $result3);
    ...
}