Anand Wu
Anand Wu

Reputation: 117

Is Perl optimized to skip remaining logic operands if the answer is already decided?

For instance, I need to match some text if $do eq 'b'. If I run this code:

if (($do eq 'b') && (/text/))
{
do stuff
}

Would perl evaluate the first parenthesis and second parenthesis no matter what or would it stop at the evaluation of the second parenthesis if the first parenthesis was false?

Follow-up question here. (I didn't know if I should make a new question or post it here)

Upvotes: 4

Views: 178

Answers (6)

Drew Shafer
Drew Shafer

Reputation: 4802

Yes. This behavior is commonly used in idiomatic perl.

Consider:

open FILE, ">$fname" or die $!;

If there is no error opening the file (open returns true), the die statement is not executed. This is not special treatment of the die routine; it is just the way perl handles logic evaluation.

Upvotes: 7

mpapec
mpapec

Reputation: 50657

No, right part of condition is not evaluated when left part is false,

if ($do eq 'b' && /text/)
{
do stuff
}

Upvotes: 2

Greg Bacon
Greg Bacon

Reputation: 139631

Yes. This behavior is called short-circuiting in the perlop documentation (emphasis added).

C-style Logical And

Binary && performs a short-circuit logical AND operation. That is, if the left operand is false, the right operand is not even evaluated. Scalar or list context propagates down to the right operand if it is evaluated.

C-style Logical Or

Binary || performs a short-circuit logical OR operation. That is, if the left operand is true, the right operand is not even evaluated. Scalar or list context propagates down to the right operand if it is evaluated.

In addition to && and || their lower-precedence cousins and and or also short-circuit.

Perl has an xor operator, but it cannot short-circuit due to the definition of exclusive-or.

Upvotes: 4

Oren
Oren

Reputation: 3248

Short answer: it stops ("short circuits" as AJ points out). You can get a ton more detail here.

Upvotes: 4

amon
amon

Reputation: 57640

Yes, Perl short circuits logical operators. This means they can be used for control flow:

say "foo" if $bar;

is the same as

$bar and say "foo";

and

if ($cond) { stuff() }

is the same as

$cond and do { stuff() }

However, the whole condition of an if has to be wrapped in parens, making your example

if ($do eq 'b' && /text/) {
  do stuff;
}

(&& is the same as and, but has higher precedence)

Upvotes: 4

mzedeler
mzedeler

Reputation: 4369

It would be

if ($do eq 'b' && /text/) {
    do stuff
}

Yes - if $do eq 'b' is false, /text/ won't be evaluated.

Upvotes: 2

Related Questions