What happens if you have a conditional operator and a postfix conditional operator in the same Perl expression?

Can anyone explain how this line works?

return $y < 0 ? - pip2 : pip2 if $x == 0; 

if $y <0 returns -pip2 , but what returns when $y >= 0 and $x != 0 ?

This line is taken from this function:

 sub _atan { my( $y, $x ) = @_; return $y < 0 ? - pip2 : pip2 if $x == 0; return atan( $y / $x ); } 
+6
syntax conditional-operator perl
source share
4 answers

The "if" postfix means that the return statement is only executed if the condition is true, therefore

 return $y < 0 ? - pip2 : pip2 if $x == 0; 

coincides with

 if ($x == 0) { return $y < 0 ? - pip2 : pip2 ; } 

If you are puzzled by the ?: trernary operator, which can be rewritten as a regular if statement to get this

 if ($x == 0) { if ($y<0) { return -pip2; } else { return pip2; } } 
+20
source share

this is the same as

 if($x == 0){ if($y<0){ return -pip2; }else{ return pip2; } } 

The whole function then becomes:

 sub _atan { my( $y, $x ) = @_; if($x == 0){ if($y<0){ return -pip2; }else{ return pip2; } }else{ return atan( $y / $x ); } } 
+7
source share

This is a good example of hard to read code.

Let's compare a few different ways to rewrite the sample code and see how we do it, while maintaining brevity and improving readability.

This ternary version only wins for brevity, but it's still hard to read:

 sub _atan { my( $y, $x ) = @_; return $x == 0 ? ($y < 0 ? -pip2 : pip2) : atan( $y / $x ); } 

I find that chain conditional statements (? :) are only read when subsequent statements fall into the else position:

 sub _atan { my( $y, $x ) = @_; return $x != 0 ? atan( $y / $x ) : $y < 0 ? -pip2 : pip2; } 

Still briefly, but readability is improving.

But what about using if and unless ? Can we use concise, readable code using them?

By nature, the direct if / else approach will be more verbose:

 sub _atan { my( $y, $x ) = @_; my $atan; if( x == 0 ) { if( $y < 0 ) { $atan = -pip2; } else { $atan = pip2; } } else { $atan = atan( $y / $x ) } return $atan; } 

It is easy to follow the foregoing and see what the result will be. So readability wins, but brevity suffers.

I find that using unless and if modifier forms provides a clean way to add short circuit logic to a piece of code:

 sub _atan { my( $y, $x ) = @_; return atan( $y / $x ) unless $x == 0; return -pip2 if $y < 0; return pip2; } 

It’s finished and readable, but it seems to me that we have more profit than we need.

So, if we introduce a conditional operator into the mix, we get

 sub _atan { my( $y, $x ) = @_; return atan( $y / $x ) unless $x == 0; return $y < 0 ? -pip2 : pip2; } 

This form is as concise as any of the above forms, but much clearer:

 sub _atan { my( $y, $x ) = @_; return atan( $y / $x ) unless $x == 0; return $y < 0 ? -pip2 : pip2; } 

Nested if / else clauses can be hard to understand. Taking a little caution when structuring your decision code can significantly improve readability and therefore maintainability, while maintaining a brief expression of the underlying logic.

The smell of code that needs to be fixed here was a baroque combination of conditional statement ( ?: With the form of the modifier of the if . By reordering the order of the tests and carefully choosing how we present the conditional logic, we were able to maintain brevity and clarify the code.

+6
source share

Too many lines used to solve the problem make it difficult to work with the code (always required to scroll). Solution with nested if 4 times longer. Imagine working with a screen 4 times smaller. My favorite syntax is:

 sub _atan { my ($y, $x) = @_; return atan ($y / $x) if $x != 0; return $y < 0 ? -pip2 : pip2; } 

The advantage of using a postfix operator is reduced if you put it on the next line. This line order (suggested by @daotoad) allows you to place a postfix condition on a simpler line.

The original syntax is also good, but I would not want to work with code containing the alleged nested if from previous posts.

+2
source share

All Articles