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!
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With