2009-09-14 5 views

Répondre

20

Le postfix "si" signifie le retour instruction n'est exécutée que si la condition est vraie, donc

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

est le même que

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

Si vous êtes intrigué par le: opérateur ternaire, qui pourrait être réécrite comme régulière si la déclaration aussi, pour obtenir cette

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

Je l'écrirais probablement en utilisant '' '' '' ($ x) {... ' –

+0

C'est l'opérateur conditionnel, pas l'opérateur ternaire. :) – Ether

+0

J'ai juste impliqué que c'était * un * opérateur ternaire, pas * l'opérateur ternaire :) –

7

son même que

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

La fonction entière devient alors:

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

C'est un bon exemple de code difficile à lire. Comparons quelques méthodes différentes pour réécrire l'échantillon de code et voyons comment nous pouvons conserver la brièveté et améliorer la lisibilité.

Cette ternaire seule version gagne par souci de concision, mais il est encore difficile à lire:

sub _atan { 
    my($y, $x) = @_; 

    return $x == 0 ? ($y < 0 ? -pip2 : pip2) 
        : atan($y/$x); 
} 

Je trouve que enchaînée opérateurs conditionnels (:) ne sont lisibles que lorsque les opérateurs suivants tombent dans la position d'autre:

sub _atan { 
    my($y, $x) = @_; 

    return $x != 0 ? atan($y/$x) : 
      $y < 0 ? -pip2   : pip2; 
} 

Encore brève, mais la lisibilité est améliorée. Mais qu'en est-il de if et unless? Pouvons-nous avoir du code concis et lisible en les utilisant aussi?

De par sa nature une approche directe if/else sera plus bavard:

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; 
} 

Il est facile de tracer à travers ce qui précède et voir ce que le résultat sera. La lisibilité gagne donc, mais la brièveté souffre.

Je trouve que l'utilisation des formulaires de modification de la déclaration de unless et if fournir un moyen propre pour ajouter une logique de court-circuit à un morceau de code:

sub _atan { 
    my($y, $x) = @_; 

    return atan($y/$x) 
     unless $x == 0; 

    return -pip2 if $y < 0; 

    return pip2; 
} 

Ceci est concise et facile à lire, mais pour moi, il semble comme nous avons plus de retours que nous avons besoin.

Donc, si nous introduisons un opérateur conditionnel au mélange, on obtient

sub _atan { 
    my($y, $x) = @_; 

    return atan($y/$x) 
     unless $x == 0;  

    return $y < 0 ? -pip2 : pip2; 
} 

Ce formulaire est aussi concis que l'une des formes ci-dessus, mais beaucoup plus facile à comprendre:

sub _atan { 
    my($y, $x) = @_; 

    return atan($y/$x) 
     unless $x == 0; 

    return $y < 0 ? -pip2 : pip2; 
} 

Nested Les clauses if/else peuvent être difficiles à comprendre. Prendre un peu de soin lors de la structuration de votre code de décision peut grandement améliorer la lisibilité et donc la maintenabilité, tout en conservant une expression concise de la logique sous-jacente.

L'odeur de code à corriger ici était la combinaison baroque de l'opérateur conditionnel (?:) avec la forme modificatrice d'instruction de if. En réorganisant l'ordre des tests et en choisissant soigneusement comment nous représentons la logique conditionnelle, nous avons pu préserver la brièveté et clarifier le code.

+0

+1 excellente réponse – friedo

+0

+1 pour expliquer les compromis dans le processus. –

2

Trop de lignes utilisées pour résoudre un problème rendent le code difficile à maintenir (toujours obligé de faire défiler). La solution avec imbriquée est 4 fois plus longue. Imaginez travailler avec un écran 4 fois plus petit. Ma syntaxe préférée est:

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

L'avantage d'utiliser un opérateur de Postfix est réduite si vous les mettez sur la ligne suivante. Cette commande de ligne (proposée par @daotoad) permet de placer la condition de suffixe sur une ligne plus simple.

La syntaxe initiale est également agréable, mais je ne voudrais pas travailler sur du code contenant le nested suggéré si des messages précédents.

+0

L'avantage d'un opérateur de postfix est le même, peu importe où vous l'avez mis. Si votre écran ne peut pas voir 24 lignes de code, vous avez d'autres problèmes. :) –

Questions connexes