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

Hello Monks, Can someone explain why the first ternary statement produces something completely different? The two ternary statements should be quivalent to the if else block that follows ... or not? I would expect this output:
rc_OK (=1) rc_OK (=1) ==== rc_OK (=1)
But instead I get this output:
check_group GRP_ADL001 0 rc_OK (=1) ==== rc_OK (=1)
code snippet
use strict; use Data::Dumper; my $checked; my $GroupDN="GRP_ADL001"; $checked->{Group}{$GroupDN}=1; #print Dumper($checked); my $rc_OK; exists($checked->{Group}{$GroupDN}) ? $rc_OK=1 : $rc_OK=check_group($G +roupDN,0); # this does NOT work $rc_OK=exists($checked->{Group}{$GroupDN}) ? 1 : check_group($GroupDN, +0); # this does work print "rc_OK (=$rc_OK)\n"; print "====\n"; if(exists($checked->{Group}{$GroupDN})){ $rc_OK=1 } else{ $rc_OK=check_group($GroupDN,0); } print "rc_OK (=$rc_OK)\n"; sub check_group{ my($group,$rc)=@_; print "check_group $group $rc\n"; return($rc); }

Replies are listed 'Best First'.
Re: Question about ternary operator
by moritz (Cardinal) on Jul 01, 2009 at 08:32 UTC
      The problem is that the assignment has a looser precedence than the ternary op.

      Shouldn't then the OP's program had reported a syntax error?

      -- 
      Ronald Fischer <ynnor@mm.st>
        No:
        $ perl -MO=Deparse,-p -e '1 ? $a = 3 : $b = 4' (($a = 3) = 4); -e syntax OK

        You see it is parsed, not just the way you'd naively expect it.

      Thx, operator precedence is sometimes a PITA, so this is what the first ternary statement should look like then
      exists($checked->{Group}{$GroupDN}) ? ($rc_OK=1) : ($rc_OK=check_group +($GroupDN,0));
        No, it should look exactly like the first statement. The ternary operator is very good if you use its value, but if you use it in void context it's just a kludge for an if statement. So
        # bad: ternary in void context: exists($checked->{Group}{$GroupDN}) ? ($rc_OK=1) : ($rc_OK=check_group +($GroupDN,0)); # good: 'if' in void context: if (exists($checked->{Group}{$GroupDN})) { $rc_OK = 1 } else { $rc_OK=check_group($GroupDN,0) } # also good: ternary in scalar context: $rc_OK = exists($checked->{Group}{$GroupDN}) ? 1 : check_group($Group +DN,0)

        So you have two good, idiomatic ways to express something, and complain that the third is a PITA?

        Thx, operator precedence is sometimes a PITA

        If the precedence was reversed, the intended use would not work.

        $y = $c ? $x1 : $x2;
        would mean
        ($y = $c) ? $x1 : $x2;

        By the way, it's called the "conditional operator". Perl has many ternary operators.