didess has asked for the wisdom of the Perl Monks concerning the following question:

Hi respectable Monks!

trying to explain ternary operator in Perl to someone, I found this "strange" (for me) behaviour:

when I use the return value of a sub in the predicate evaluation of a ternary operation,

nothing seems to work when this evaluation happens between parentheses. Some explanation ?

The example : This code :

sub get1 { return 1; } print get1() ? "1: Flag is up\n" : "1: Flag is not up\n"; print &get1 ? "2: Flag is up\n" : "2: Flag is not up\n"; print (get1()) ? "3: Flag is up\n" : "3: Flag is not up\n"; print (&get1 ) ? "4: Flag is up\n" : "4: Flag is not up\n";
gives this output :
1: Flag is up 2: Flag is up
Where did cases 3 and 4 disappear ?

Replies are listed 'Best First'.
Re: parentheses around a function call in a ternary choice
by moritz (Cardinal) on Jun 23, 2009 at 20:56 UTC
    print (...) is always parsed as a function call print( ... ) (independently of what comes afterwards), so your code parses as
    ( print get1() ) ? ... : ...;

    use warnings will make that line complain about useless constants in void context, which the rest of the line actually is.

    BTW Perl 6 uses whitespaces to disambiguate, so print(...) and print (...) are really two different things (which seems to be what new Perl programmers expect).

      Thank you! it's so obvious (afterwards ;-) !
Re: parentheses around a function call in a ternary choice
by FunkyMonk (Bishop) on Jun 23, 2009 at 21:01 UTC
    In addition to moritz's comments, you can fix your example by using
    ... print +(get1()) ? "3: Flag is up\n" : "3: Flag is not up\n"; print +(&get1 ) ? "4: Flag is up\n" : "4: Flag is not up\n"

    which causes the output to change to...

    ... 3: Flag is up 4: Flag is up


    Unless I state otherwise, all my code runs with strict and warnings
      To be very honest, the warnings coming when using "warnings"

      do not explain very much to me !

      (which constants are we warned about ?)

      But your explanations do explain all clearly!

      Thanks to all

        a successful print returns true (see print). So your prints are equivalent to

        1 ? "3: Flag is up\n" : "3: Flag is not up\n";

        and that's a constant expression that evaluates to

        "3: Flag is up\n";

        That's a constant that isn't used for anything -- a constant in void context.

        When you get errors or warnings you don't understand try adding use diagnostics;. It will try to explain the error or warning given.


        Unless I state otherwise, all my code runs with strict and warnings
Re: parentheses around a function call in a ternary choice
by Marshall (Canon) on Jun 23, 2009 at 22:58 UTC
    Other comments well taken. I wouldn't use this deprecated &get1 syntax. get1() is the preferred way.