34

Which of these subroutines is not like the other?

sub or1 {
    my ($a,$b) = @_;
    return $a || $b;
}

sub or2 {
    my ($a,$b) = @_;
    $a || $b;
}

sub or3 {
    my ($a,$b) = @_;
    return $a or $b;
}

sub or4 {
    my ($a,$b) = @_;
    $a or $b;
}

I came to Perl 5 from C and Perl 4 and always used || until I saw more scripts using or and I liked the way it looked. But as the above quiz shows, it's not without its pitfalls for the unwary. For people who use both constructs or who use a lot of or, what rules of thumb do you use to decide which construct to use and make sure the code is doing what you think it is doing?

brian d foy
  • 129,424
  • 31
  • 207
  • 592
mob
  • 117,087
  • 18
  • 149
  • 283
  • 7
    I'll take Japan-US relations for $200, Trebek. – Rap Oct 03 '09 at 02:31
  • Possible duplicate of [What is the difference between "||" and "or" in Perl?](http://stackoverflow.com/questions/1136583/what-is-the-difference-between-and-or-in-perl) – user May 16 '16 at 00:24

5 Answers5

42

Due to the low precedence of the 'or' operator, or3 parses as follows:

sub or3 {
    my ($a,$b) = @_;
    (return $a) or $b;
}

The usual advice is to only use the 'or' operator for control flow:

@info = stat($file) or die;

For more discussion, see the perl manual: http://perldoc.perl.org/perlop.html#Logical-or-and-Exclusive-Or

Igor ostrovsky
  • 7,282
  • 2
  • 29
  • 28
18

What rules of thumb do you use to decide which construct to use and make sure the code is doing what you think it is doing

The operator precedence rules.

|| binds tightly, or binds weakly. There is no "rule of thumb".

If you must have a rule of thumb, how about "only use or when there is no lvalue":

or:

open my $fh, '>', 'file' or die "Failed to open file: $!"

||:

my $greeting = greet() || $fallback || 'OH HAI';

I agree with MJD about avoiding parens; if you don't know the rules, look them up... but don't write (open(my $fh, '>', 'file')) or (die("Failed to open file: $!")) "just to be sure", please.

jrockway
  • 42,082
  • 9
  • 61
  • 86
8

In Perl 5, "or" and "and" have lower precedence than "||" and "&&". Check out this PerlMonks thread for more info:

http://www.perlmonks.org/?node_id=155804

perimosocordiae
  • 17,287
  • 14
  • 60
  • 76
2

My guess is that or3 is different.

I'm not really a Perl guy, but it looks like 1, 2, and 4 all explicitly return booleans. I'm guessing 3 has side effects, such as returning $a or something crazy like that.

looks down

Hey, I was right.

Stefan Kendall
  • 66,414
  • 68
  • 253
  • 406
2

Both versions are short-circuiting in Perl, but the 'textual' forms ('and' and 'or') have a lower precedence than their C-style equivalents.

http://www.sdsc.edu/~moreland/courses/IntroPerl/docs/manual/pod/perlop.html#Logical_And

Ed S.
  • 122,712
  • 22
  • 185
  • 265