Anand Wu
Anand Wu

Reputation: 117

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

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?

Upvotes: 2

Views: 563

Answers (4)

Lorkenpeist
Lorkenpeist

Reputation: 1495

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);
    ...
}

Upvotes: 1

Borodin
Borodin

Reputation: 126742

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()

Upvotes: 5

mob
mob

Reputation: 118665

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).

Upvotes: 3

Charles Engelke
Charles Engelke

Reputation: 5649

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.

Upvotes: 8

Related Questions