Operator precedence with return and if/unless

Discussion in 'Perl Misc' started by Jens Thoms Toerring, Jan 31, 2010.

  1. 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 ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Jan 31, 2010
    #1
    1. Advertising

  2. Jens Thoms Toerring

    Uri Guttman Guest

    >>>>> "JTT" == Jens Thoms Toerring <> writes:

    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 ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
     
    Uri Guttman, Jan 31, 2010
    #2
    1. Advertising

  3. Ben Morrow <> wrote:

    > Quoth (Jens Thoms Toerring):
    > >
    > > 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?


    > '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
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Jan 31, 2010
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Master of C++
    Replies:
    4
    Views:
    746
    Karl Heinz Buchegger
    Feb 7, 2005
  2. Richard Bos

    && and || Operator precedence enforcement

    Richard Bos, Jan 19, 2004, in forum: C Programming
    Replies:
    18
    Views:
    626
    Dan Pop
    Jan 20, 2004
  3. siliconwafer

    operator precedence with && and comma

    siliconwafer, Jul 29, 2005, in forum: C Programming
    Replies:
    21
    Views:
    653
  4. Gábor SEBESTYÉN

    Unless unless

    Gábor SEBESTYÉN, Jun 17, 2005, in forum: Ruby
    Replies:
    3
    Views:
    176
    Gábor SEBESTYÉN
    Jun 17, 2005
  5. Andrew Savige
    Replies:
    2
    Views:
    251
    Andrew Savige
    Mar 26, 2009
Loading...

Share This Page