In Perl - can a short circuit evaluation be disabled if needed?

梦想的初衷 提交于 2019-12-24 00:15:47

问题


This is a follow-up question for this one.

For example, let's say I have three procedures that I need to run no matter what and exit if all of them return 1.

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

Because Perl is using short-circuit evaluation, the code may or may not execute subs &proc2 and &proc3 depending on preceding operands (if an operand is false the following operands won't be executed; more info here and on wiki). If needed, is there any way to turn the feature off?


回答1:


You can use the multiplication operator

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

This will evaluate all three operands and evaluate to false if any one of them is false (zero).

If you are worried about warnings about uninitialized values, you can use bitwise-and with the !! cast-to-boolean pseudo-operator:

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

which will do pretty much the same thing. The cast-to-boolean is necessary because the result of a bitwise-and of two arbitrary true values may still be false (e.g., 1 & 2 evaluates to 0).




回答2:


You could just evaluate every clause to temporary variables, then evaluate the entire expression. For example, to avoid short-circuit evaluation in:

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

write:

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

Both conditionals will be evaluated. Presumably, you want more complex conditions with side effects, otherwise there's no reason to evaluate the second condition if the first is false.




回答3:


You could write

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

Whatever you do, you shouldn't call subroutines using the ampersand syntax, like &proc1. That has been wrong for many years, replaced by proc1()




回答4:


I'm not aware of any way to disable short-circuit evaluation, but you can evaluate each component at the beginning of the body of the loop, and break if any of the conditions is false.

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


来源:https://stackoverflow.com/questions/17178629/in-perl-can-a-short-circuit-evaluation-be-disabled-if-needed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!