Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ternary producing different results than If [duplicate]

EDIT: For anyone who has arrived here with this issue, I found this documented almost verbatim in the perldoc at https://perldoc.perl.org/perlop#Conditional-Operator

In writing a simple subroutine, I found I kept getting incorrect results using the ternary operator, but correct results using a more simple if statement. I'm sure there is an explanation, but I'm simply not seeing it.

When fed the following input:

my @input = (4, 5, 7, 8, 1, 2, 3, 0);
sum_square_even_root_odd(\@input);

The result should be 91.61.

The following (using Ternary) results in 175.61.

sub sum_square_even_root_odd {
    my ($nums) = @_;
    my $sum = 0;
    map { $_ % 2 ? $sum+= sqrt $_ : $sum += $_ ** 2 } @{$nums};
    return sprintf('%.2f', $sum) + 0;
};

However, the result is what is expected when simply changed to an if statement

sub sum_square_even_root_odd {
    my ($nums) = @_;
    my $sum = 0;
    map { if( $_ % 2 ) { $sum+= sqrt $_ } else { $sum += $_ ** 2 } } @{$nums};
    return sprintf('%.2f', $sum) + 0;
};

Can someone explain why this is happening? I assume a value I am not expecting is sneaking it's way into $_, but I'm unsure as to why.

Thank you!

like image 200
Myersguy Avatar asked Dec 30 '22 16:12

Myersguy


1 Answers

It is, in fact, a precedence issue. The way to diagnose precedence problems is with B::Deparse:

$ perl -MO=Deparse,-p -e 'map { $_ % 2 ? $sum+= sqrt $_ : $sum += $_ ** 2 } @ARGV'
map({((($_ % 2) ? ($sum += sqrt($_)) : $sum) += ($_ ** 2));} @ARGV);
-e syntax OK

Aha, the : has higher precedence than the += to its right. To do what you mean, use parentheses on the last clause of the ternary operation:

$_ % 2 ? $sum+= sqrt $_ : ($sum += $_ ** 2)
like image 158
mob Avatar answered Jan 05 '23 16:01

mob