web-dev-qa-db-fra.com

Utilisation de "si" ou de "moins que" pour les conditions Perl

Quelles sont les directives pour une meilleure utilisation de if contre unless dans le code Perl? Existe-t-il de bonnes raisons de préférer l’un ou l’autre dans certaines situations?

49
JSBձոգչ

Dans Perl Best Practices, le conseil est de ne jamais utiliser unless. Personnellement, je pense que c'est de la folie.

J'utilise unless chaque fois qu'il y a une condition simple que j'écrirais autrement sous la forme if( ! ... ). Je trouve la version unless plus lisible, surtout si elle est utilisée comme postfixe:

do_something() unless $should_not_do_that;

Je recommande d'éviter unless à chaque fois que les choses se compliquent, comme lorsque vous aurez des blocs elsif ou else. (Heureusement ou peut-être malheureusement, selon votre point de vue, il n'y a pas elsunless)

De plus, chaque fois qu'un conditionnel est une expression complexe composée d'autres booléens. Par exemple, 

unless( $foo and !$bar )

Est sacrément déroutant, et n’a aucun avantage sur l’équivalent if

58
friedo

À part un cas ésotérique1 unless est simplement un sucre syntaxique pour if !. Il existe pour vous permettre d'écrire du code plus clair et plus expressif. Il devrait être utilisé quand il atteint cet objectif et évité quand il le gêne.

Je trouve que unless est le plus utile pour le contrôle de flux dans les boucles. par exemple.

while (<$fh>) {
    next unless /\S/;
    # ...
}

Pour les simples négations, je le trouve plus clair qu’un if négatif - il est facile de rater ce ! principal en lisant le code.

unless ($condition) {
    do_something();
}

if (!$condition) {
    do_something();
}

Mais n'écrivez pas unless ... else, car ce n'est que discordant.

Sous forme postfixe, il fournit un indice sur le chemin attendu par le code.

do_normal_thing() unless $some_unlikely_condition;


1) La dernière expression évaluée est différente, ce qui peut affecter le comportement des sous-programmes sans une return explicite.

35
Michael Carman

Une règle de base est que «à moins que» devrait probablement être utilisé rarement.

Il est particulièrement utile sous la forme postfixe, par exemple:

delete_old_widgets() unless $old_widget_count == 0

Les situations où vous ne devriez jamais utiliser à moins que:

  • avec une condition composée (et, ou, non)
  • avec une clause else
12
Grant McLean

J'ai récemment passé une heure à essayer d'expliquer à quelqu'un comment deux clauses "à moins que" ne soient imbriquées, il était difficile de les décrypter sans avoir à les inverser si des instructions avec une logique booléenne.

Si vous essayez de le convertir en anglais, cela vous aidera à vous guider.

Un simple à moins que cela fonctionne bien. Par exemple.

"À moins que vous ne soyez silencieux, je vais vous ignorer".

unless ($quiet) {
    ignore();
}

Bien que je pense que cela fonctionne aussi bien

'Si tu n'es pas tranquille, je vais t'ignorer'

if (not $quiet) {
    ignore();
}

quand ça commence à devenir compliqué, c'est quand vous avez la négation.

'Sauf si tu n'es pas bruyant, je vais t'ignorer'

unless ( ! $noisy) {
    ignore();
}

Bien mieux écrit comme

"Si vous êtes bruyant, je vais vous ignorer"

if ($noisy) {
    ignore();
}

Donc, n'utilisez pas de 'sauf si' si vous avez également un négatif.

Aussi, n'utilisez pas 'sauf si'

unless ($quiet) {
    ignore();
}
else {
    give_a_sweet();
}

"À moins que vous ne soyez silencieux, je vous ignorerai, sinon je vous donnerai un bonbon"

Changez-le en inversant la condition.

if ($quiet) {
    give_a_sweet();
}
else {
    ignore();
}

"Si vous êtes tranquille, je vais vous donner un bonbon, sinon je vous ignorerai".

avec plus d'une condition, il est en désordre.

unless ($quiet and not $fidgit) {
    punish();
}

«À moins que vous ne restiez silencieux et que vous ne restiez pas fidèle, je vais vous punir».

(désolé ma compréhension échoue ici!)

encore une fois, le nier.

if (not $quiet or $fidgit) {
    punish();
}

'Si vous n'êtes pas tranquille ou si vous restez fidèle, je vous punirai'.

le problème de l'utilisation de "sauf", même pour les cas les plus simples, souvent (par vous-même ou par

J'espère que cela indique clairement quand vous devriez ou ne devriez pas utiliser à moins que?

(sauf si vous n'avez pas un autre avis?)

9
user3043717

Bien que je comprenne les motivations de ce type de questions, je ne crois pas qu’il soit vraiment judicieux de résumer l’utilisation de quelque chose comme unless dans des règles empiriques concrètes. Ceci, comme beaucoup de syntaxe auxiliaire dans Perl, est fourni à titre de commodité mineure aux programmeurs pour les aider à s'exprimer plus clairement à leur propre discrétion; J'ai vu autant de choses dire à plus d'un titre par les développeurs principaux dans "Programmation Perl". Il n'y a pas de but supérieur ou de rationalisation. Je sais bien que la question est affinée, mais la seule contrainte que je voudrais imposer à son utilisation est de veiller à ce qu’elle serve son objectif plus général de clarification du code. Si c'est le cas, alors tout va bien. Reconnaître si le code est compréhensible est intuitif en soi et ne peut pas être réduit à une poignée de conditions d'utilisation trop généralisées concernant chaque nuance de la syntaxe intégrée des modificateurs/opérateurs/dans son ensemble, ainsi que sur les contraintes et les directives dans les projets de groupe. Je ne pense pas qu'il serait logique de couper les cheveux si finement.

2
cikkle

Mon avis serait de ne jamais utiliser à moins que. Mes raisons sont:

  • Je pense que la syntaxe rend le code plus difficile à lire. Avoir une seule méthode pour faire un si rend la chose plus simple et plus cohérente.
  • Si vous avez besoin d’ajouter ultérieurement une autre instruction, vous devriez vraiment changer le moins, sauf un si. C'est simplement plus facile si c'est déjà un si.
  • Si la logique à l'intérieur de l'instruction less devient plus complexe, vous pouvez vous retrouver avec un code impair du type "à moins que (x == 5 && y! = 7). Ceci est étrange car il y a un double négatif sur la deuxième vérification.
  • Il y a d'autres façons de nier les choses, par exemple x! = 5
  • C'est plus cohérent avec d'autres langues. Je ne connais aucune autre langue qui comporte une déclaration sauf si et je pense qu'il y a une très bonne raison à cela.

En Perl, il y a vraiment 4 façons d'écrire une instruction if, si, à moins que, puis en mettant la vérification en fin de ligne au lieu du début. Je préfère de loin une méthode cohérente unique compatible avec d’autres langues.

Juste ma valeur de 0,02 $.

1
MikeKulls

À propos ...

Dans Perl Best Practices, le conseil est de ne jamais utiliser à moins que. Personnellement, Je pense que c'est la folie.

Après plus de 20 ans préférant Perl à toutes ses alternatives (dont la plupart n'existeraient pas si Perl n'avait pas fourni le gabarit), non seulement je souscris au verdict de "folie", je suis surpris d'apprendre que "Meilleures pratiques 'veut s'en débarrasser.

Cela dit, je préfère fortement le code écrit pour plus de clarté, par opposition aux alternatives implicitement obscurcies que certains programmeurs Perl adoptent "juste parce qu'ils le peuvent". "less" est l'opposé sans équivoque de "if" et constitue donc une alternative très utile à l'intégration d'une négation dans un conditionnel "if", particulièrement si le conditionnel contient plusieurs opérateurs. Et cette raison s'applique même si elle est suivie par else/elsif. 

1
edwin

Juste un avis personnel peut-être, mais j'aime bien utiliser sauf si la condition initiale commence par un!

0
David Brunelle

La syntaxe if (! $ Condition) équivaut à moins que ($ condition), et de même si vous permutez le NOT'ing de la condition.

Personnellement, je préfère utiliser uniquement les instructions IF. Pourquoi? Parce que c'est moins à mémoriser. Si vous avez 100 lignes de code, dont la moitié avec less () et l'autre avec if (), vous devrez passer plus de temps à le déboguer que s'il ne s'agissait que d'instructions if.

Vous pouvez "maîtriser" le jeu à moins que et si, cependant, pour que le passage entre les deux ne prenne pas de temps du tout. Mais il ne s’agit pas seulement de si () et de moins que (). N'oublie pas ça ...

if($condition) {
    #passed-condition code
} else {
    #failed-condition code
}

...est équivalent à...

unless(!$condition) {
    #passed-condition code
} else {
    #failed-condition code
}

Mais qu'en est-il de if () {...} elsif () {...}? Comment feriez-vous un équivalent de cela si () {...} elsunless () {...}? Plus la logique est compliquée, plus il devient difficile de passer de if () à moins de (). Moins vous aurez à vous souvenir et à garder votre mémoire en équilibre, plus vous serez en mesure de déboguer votre propre code.

0
HoldOffHunger