# Operator precedence with return and if/unless

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on

Hi,

after gotten bitten by it (again) I wonder once more if
there are good reasons why in

perl -e 'sub x { return 1 and 0 } print x() . "\n";'

the 'return' seems to have a higher "precedence" than the
'and' operator, i.e. () returns 1, while for

perl -e 'sub x { return 1 && 0 } print x() . "\n";'

0 is returned. On the other hand with

perl -e 'print "bla\n" if 1 and 0;'
perl -e 'print "bla\n" if 1 && 0;'

'if' (and 'unless') has a lower "precedence" then both 'and' and
'&&', thus "bla\n" isn't printed out in either case. And the same
holds, of course, for the 'or' and '||' operators...

That doesn't look too logical or intuitive to me, so is there a
reason for that I'm missing to see or is it for some historical
reasons? Is there anything that could happen after a 'return',
so is 'return 1' an expression that has a value that could be
'and'ed with something following it?

Regards, Jens
--
\   Jens Thoms Toerring  ___      jt@toerring.de
\__________________________      http://toerring.de

## Re: Operator precedence with return and if/unless

JTT> there are good reasons why in

JTT> perl -e 'sub x { return 1 and 0 } print x() . "\n";'

JTT> the 'return' seems to have a higher "precedence" than the
JTT> 'and' operator, i.e. () returns 1, while for

JTT> perl -e 'sub x { return 1 && 0 } print x() . "\n";'

JTT> 0 is returned. On the other hand with

JTT> perl -e 'print "bla\n" if 1 and 0;'
JTT> perl -e 'print "bla\n" if 1 && 0;'

JTT> 'if' (and 'unless') has a lower "precedence" then both 'and' and
JTT> '&&', thus "bla\n" isn't printed out in either case. And the same
JTT> holds, of course, for the 'or' and '||' operators...

'and' and '&&' do the exact same operation. the ONLY difference is
precedence. this is true for all the boolean ops which have symbolic and
spelled out names. the spelled out names were added to perl5 later. they
were made lower precedence on purpose so you could do boolean ops which
bind lower than things such as assignment, func calls, etc.

JTT> That doesn't look too logical or intuitive to me, so is there a
JTT> reason for that I'm missing to see or is it for some historical
JTT> reasons? Is there anything that could happen after a 'return', so
JTT> is 'return 1' an expression that has a value that could be
JTT> 'and'ed with something following it?

the reason they are there is so you can have a CHOICE in precedence. it
allows for different syntax and some like it one way or the other.

look at these two common lines:

open( my \$foo, \$file ) || die "can't open \$file \$!" ;
open my \$foo, \$file or die "can't open \$file \$!" ;

the 'or' allows you to drop the () on the open call.

a good rule (courtesy of peter scott) about when to use which form is:

use the symbolic forms (||, &&, !) when doing a boolean expression
use the spelled forms( or, and, not) when doing flow control

the precedence levels work best in those situations.

\$foo = \$bar and last ;
\$foo = \$bar || \$default ;

uri

--
Uri Guttman  ------  uri@stemsystems.com  --------  http://www.sysarch.com --
-----  Perl Code Review , Architecture, Development, Training, Support ------
---------  Gourmet Hot Cocoa Mix  ----  http://bestfriendscocoa.com ---------

## Re: Operator precedence with return and if/unless

Quoth jt@toerring.de (Jens Thoms Toerring):

'return' parses as a listop, so for consistency it should behave like
'print' rather than like 'if'. You might as well ask why 'exit' or 'die'
(or indeed POSIX::_exit) also behave the same way.

Ben

## Re: Operator precedence with return and if/unless

I think my expectations were wrong in not realizing 'return'
to behave more "function-like" (probably derived from the way
it is done in C which I'm perhaps a bit more familiar with).
When I now consider 'return' as being a kind of function I can
come up an example like

perl -e 'sub x {return 0 or print "FOO\n"} x()'

that doesn't print out "FOO" while

perl -e 'sub x {return 0 || print "FOO\n"} x()'

does - and it starts to make some sense to me. What I had been
looking at before for some time were things like

return \$x->has_some_property or \$x->has_some_other_property;

versus

return \$x->has_some_property || \$x->has_some_other_property;

where the diferrence in behaviour was a bit surprising while I
still was assuming that 'return' was a kind of 'built-in opera-
tor' not unlike 'if' or 'unless'.

Thanks and best regards, Jens
--
\   Jens Thoms Toerring  ___      jt@toerring.de
\__________________________      http://toerring.de