Après une brève interruption, nous voici de retour pour une seconde année de La pratique de Perl. Ce mois ci, Rob m'a demandé d'écrire un petit document sur la lisibilité des programmes Perl. J'ai donc commencé à travailler dans ce but, mais j'ai rapidement dérivé vers la question de la maintenabilité de code écrit en Perl. Ceci m'a chagriné jusqu'à ce que je me rende compte que la maintenabilité est la principale raison nous poussant à exiger du code lisible. Si une fois écrit, un code n'avait jamais à être relu, la motivation d'écrire du code lisible serait moins importante (note: mais elle serait quand même souhaitable). Ce point de philosophie traité, passons aux différents petits trucs biens utiles que j'ai accumulés au fil des ans.
grep($array{$_}++, @list); # Mauvais ! for (@list) { # OK $array{$_} = 1; }Je prétends que la seconde forme est préférable à la première car elle indique ce qui ce passe : Nous itérons sur
@liste
et
initialisons chaque entrée du tableau %array
à une valeur
non nulle. (L'affectation est plus lisible que
l'auto-incrémentation). Il existe d'autres façons plus verbeuses
d'écrire la boucle "for" ci-dessus. A vous de choisir celle que vous
préférez, mais éviter d'utiliser grep()
comme opérateur
d'itération. En général j'optimise la lisibilité du code plutôt que
son exécution.
Autre exemple, examinons les deux boucles perpétuelles suivantes :
while (1) { # Mauvais! ... } for ( ;; ){ # OK ... }La seconde forme saute mieux aux yeux, elle montre clairement au lecteur que quelque chose d'important est attendu.
Toujours au chapitre des boucles, examinons une autre règle de communication entre l'auteur du code et ses relecteurs : "Soyez brefs". Les "goto" et les "break" sur plusieurs niveaux sont tous deux à éviter pare ce qu'ils empêchent le lecteur d'avoir une vision d'ensemble du flux d'exécution du code. J'ai recherché des exemples illustrant cette règle, mais je n'en ai pas trouvés qui tiennent dans l'espace alloué à cet article. Je pense cependant en avoir assez dit.
until
à la place de
while
et unless
à la place de
if
.
&usage() unless (@ARGV); until ($value > $LIMIT) { ... }Vous augmenterez largement la lisibilité de votre code en supprimant les négations dans vos expressions. Perl peut se lire comme de la prose si vous utilisez attentivement ses noms symboliques.
Avec les opérateurs conditionnels postfixés, faites bien attention à placer la partie la plus importante de l'instruction au début de la phrase. C'est pourquoi il vaut mieux écrire :
open(...) || die ... ; # Recommandéque
die ... unless open(...); # Pas terrible !Le propos de cette instruction est d'associer un "file handle" à un fichier ou à un sous process. Le code
die()
n'intervient
que pour traiter les exceptions.
De la même façon, évitez de surcharger les expressions conditionnelles avec des opérations qui manipulent les données du programme ou qui ont d'autres effets de bords. Évaluer d'abord une expression pour choisir une branche d'exécution puis exécuter vos opérations.
Perl est extrêmement permissif au sujet des parenthèses dans les listes d'arguments. Parenthèsez toujours les arguments de vos fonctions. Un exemple classique de cette règle est fourni par le "Camel book"(*).
print (1+2)*3, "\n"; # INCORRECT!Ceci imprime la valeur de l'expression entre parenthèses, i.e. le nombre trois sans saut de ligne. Cette instruction est syntaxiquement correcte, (un bon point si vous trouvez exactement ce qu'il advient du reste de la ligne), et l'interpréteur Perl ne bronchera pas, mais la sortie sera tout à fait différente de celle produite par :
print((1+2)*3, "\n"); # CORRECTqui est certainement ce que souhaitait l'auteur du code.
Si vous n'avez besoin que de quelques valeurs retournées par une fonction, s'il vous plaît, éviter d'utiliser des variables inutiles. En d'autre termes, faites :
($login, $name, $home) = (getpwent)[0,6,7]; # Bonplutôt que :
($login, $dummy, $dummy $dummy, $dummy, $dummy, $name, $home) = getpwent; # MauvaisEn dehors de l'économie de saisie, la première forme montre précisément la partie de l'information qui est utilisée.
undef
ou une affectation avant de les utiliser pour la première fois. Ceci
aide à éviter des erreurs qui pourraient être introduites par des
futures modifications.
Les paramètres implicites des fonctions sont subtiles. Vous pouvez
parfaitement considérer qu'une fonction Perl s'appliquera à
$_
ou @_
si vous ne lui donnez pas
d'argument. C'est une particularité bien pratique et je l'utilise
constamment (c'est trop pratique pour s'en passer je
suppose). Cependant cela rend le code Perl particulièrement obscure
pour un novice. En quelques occasions j'ai même constaté des
comportements anormaux parce que @_
ne contenait pas ce
que je pensais. Sur un point encore plus trivial, je recommande
également de toujours utiliser le caractère < pour ouvrir un
fichier en lecture, même si c'est l'option par défaut de
open()
.
Ne codez jamais en dur les chemins des fichiers ou les constantes dans vos programmes. Affectez ces valeurs à des variables AU DÉBUT de votre programme. Par exemple, voici les quelques premières lignes d'une application que j'ai écrite pour manipuler un "jukebox" optique sur le réseau :
#!/usr/bin/perl $jukehost = `gator'; $nfsjukedir = `/rd/juke'; $realjukedir = `/export/jb/jb0'; $localjukedir = `/jukebox'; $remotecmd = `/usr/local/etc/jbadm';Quand un code est écrit de cette façon, le maintenir est un jeu d'enfant.
Refermez toujours vos fichiers et répertoires dès que vous avez fini de les utiliser. Cela évitera les pénuries de file descripteurs dans votre application en même temps que ça la protégera contre les effets de bords causés par des modifications ultérieure, et cela rendra votre code plus clair pour l'hypothétique lecteur externe.
Pour éviter ce bourbier, (je sais par exemple que tout le monde déteste le style de mes accolades), je suggère une simple et unique règle. Choisissez un standard que tout le monde accepte dans votre organisation et tenez vous y. Même un mauvais standard est préférable à pas de standard du tout. Si vous avez à maintenir du code développé à l'extérieur, conservez alors les conventions qui ont été utilisées par les auteurs originaux.
Un bon point de départ est fourni par un document disponible sur le réseau, Recommended C Style and Coding Standards (il a été préparé par un groupe de travail aux "Bell Labs" et a été modifié par Henry Spencer, David Keppel, et Mark Brader). Il est disponible sous une forme électronique /pub/cstyle.tar.Z que vous pouvez obtenir par ftp depuis ftp.cs.washington.edu.
Traduction de ;login: Vol. 19 No. 6, December 1994.
Dernière édition: 16 mars 1997 phb
Original 11/26/96ah
Back to the original
Retour à l'index