note
stevieb
<p>They are identical in functionality. Where they differ is precedence. <c>||</c> and <c>&&</c> have a higher precedence than <c>and</c> and <c>or</c>. Observe:</p>
<c>
use warnings;
use strict;
my $one = 1;
$one += 0 || warn "||\n";
$one += 0 or warn "or\n";
$one += 0 && warn "&&\n";
$one += 0 and warn "and\n";
</c>
<p>Output:</p>
<c>
||
and
</c>
<p>All examples attempt the same thing. Add <c>$one</c> to zero, which should obviously result in true (1). However, in the <c>||</c> example, instead of <c>$one</c> being added to zero, the <c>||</c> has a higher precedence than <c>+=</c>, meaning that the <c>||</c> binds to the zero before the addition-assignment happens, so the left hand side is false, therefore, the <c>warn</c> is executed. In the <c>or</c> line, the <c>+=</c> has a higher precedence, meaning the left hand side is evaluated to true, so the <c>warn</c> is ignored.</p>
<p>It's similar for the <c>&&</c> and <c>and</c>. <c>&&</c> binds to the zero before the <c>+=</c>, so the left side is always going to be false, so the right side (<c>warn</c>) is never evaluated. With <c>and</c>, the addition happens first, then the <c>and</c> evaluation and because the LHS is true, the <c>warn</c> is executed.</p>
<p>Clear as mud? Good. Whenever you're using <c>and or && ||</c> and you get results you don't expect, it's almost always related to precedence, especially in long convoluted evaluations where you're using negations and stuff.</p>
<p>Parens allow you to create your own precedence:</p>
<c>
($one += 0) || warn "||\n";
</c>
<p>There, whatever is in parens will be evaluated first before the <c>||</c> is brought into the mix. In this case, the <c>||</c> warning isn't thrown like it was above.</p>
11134647
11134647