What is the difference between "||" and "or" in Perl?
Asked Answered
G

4

52

What is the difference between the C-style operators &&, ||, ... and their Perl human-readable version "and", "or", ...?

It seems that Internet code uses them both:

open (FILE, $file) or die("cannot open $file");
open (FILE, $file) || die("cannot open $file");
Gilbertson answered 16/7, 2009 at 9:58 Comment(2)
See perldoc perlop for a good precedence chart, and see the section on "Logical or" for more examples: perldoc.perl.org/…Unwisdom
Also, use lexical file handles and the three-argument form of open. Include the error returned by the system in the argument to die: open my $file_h, '<', $file or die "Cannot open '$file': $!";Villalpando
P
53

From Perl documentation:

OR

List operators

On the right side of a list operator, it has very low precedence, such that it controls all comma-separated expressions found there. The only operators with lower precedence are the logical operators "and", "or", and "not", which may be used to evaluate calls to list operators without the need for extra parentheses.

Logical or, defined or, and exclusive or.

Binary "or" returns the logical disjunction of the two surrounding expressions. It's equivalent to ||, except for the very low precedence. This makes it useful for control flow

print FH $data or die "Can't write to FH: $!";

This means that it short-circuits: i.e., the right expression is evaluated only if the left expression is false. Due to its precedence, you should probably avoid using this for assignment, only for control flow.

$a = $b or $c; # Bug: this is wrong
($a = $b) or $c; # Really means this
$a = $b || $c; # Better written this way

However, when it's a list-context assignment and you're trying to use "||" for control flow, you probably need "or" so that the assignment takes higher precedence.

@info = stat($file) || die; # Oops, scalar sense of stat!
@info = stat($file) or die; # Better, now @info gets its due

Then again, you could always use parentheses.

||

If any list operator (print(), etc.) or any unary operator (chdir(), etc.) is followed by a left parenthesis as the next token, the operator and arguments within parentheses are taken to be of highest precedence, just like a normal function call.


For example, because named unary operators have higher precedence than ||:

chdir $foo || die; # (chdir $foo) || die
chdir($foo) || die; # (chdir $foo) || die
chdir ($foo) || die; # (chdir $foo) || die
chdir +($foo) || die; # (chdir $foo) || die

Partiality answered 16/7, 2009 at 13:59 Comment(1)
Accepted answer, since it's more complete than Dave Hinton'sGilbertson
A
55

!, &&, ||, and ^ have high precedence such that they are useful in constructing an expression; not, and, or, and xor have low precedence such that they are useful for flow control between what are essentially different expressions.

Antoineantoinetta answered 17/7, 2009 at 2:41 Comment(1)
I like this answer more than the accepted answer, much shorter and gives you the answer you need.Antin
P
53

From Perl documentation:

OR

List operators

On the right side of a list operator, it has very low precedence, such that it controls all comma-separated expressions found there. The only operators with lower precedence are the logical operators "and", "or", and "not", which may be used to evaluate calls to list operators without the need for extra parentheses.

Logical or, defined or, and exclusive or.

Binary "or" returns the logical disjunction of the two surrounding expressions. It's equivalent to ||, except for the very low precedence. This makes it useful for control flow

print FH $data or die "Can't write to FH: $!";

This means that it short-circuits: i.e., the right expression is evaluated only if the left expression is false. Due to its precedence, you should probably avoid using this for assignment, only for control flow.

$a = $b or $c; # Bug: this is wrong
($a = $b) or $c; # Really means this
$a = $b || $c; # Better written this way

However, when it's a list-context assignment and you're trying to use "||" for control flow, you probably need "or" so that the assignment takes higher precedence.

@info = stat($file) || die; # Oops, scalar sense of stat!
@info = stat($file) or die; # Better, now @info gets its due

Then again, you could always use parentheses.

||

If any list operator (print(), etc.) or any unary operator (chdir(), etc.) is followed by a left parenthesis as the next token, the operator and arguments within parentheses are taken to be of highest precedence, just like a normal function call.


For example, because named unary operators have higher precedence than ||:

chdir $foo || die; # (chdir $foo) || die
chdir($foo) || die; # (chdir $foo) || die
chdir ($foo) || die; # (chdir $foo) || die
chdir +($foo) || die; # (chdir $foo) || die

Partiality answered 16/7, 2009 at 13:59 Comment(1)
Accepted answer, since it's more complete than Dave Hinton'sGilbertson
R
51

The only difference is their precedence.

open  FILE,  $file  or die("cannot open $file");   # This works
open (FILE,  $file) or die("cannot open $file");   # ...because it means this
open  FILE,  $file  || die("cannot open $file");   # This doesn't work
open  FILE, ($file  || die("cannot open $file"));  # ...because it means this
Rashad answered 16/7, 2009 at 10:1 Comment(2)
Precedence compared to what? The comma operator?Indeliberate
Precedence compared to list operators. I hope my edit makes things clearer.Rashad
R
13

The "&&" and "||" operators have higher precedence than their "and", "or" counterparts.

Razorbill answered 16/7, 2009 at 10:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.