Operator precedence with return and if/unless

  • Thread starter Jens Thoms Toerring
  • Start date
J

Jens Thoms Toerring

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
 
U

Uri Guttman

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
 
J

Jens Thoms Toerring

Ben Morrow said:
Quoth (e-mail address removed) (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.

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,690
Latest member
MacGyver

Latest Threads

Top