Précédent   Forum du club des développeurs et IT Pro > Autres langages > Perl > Langage
Langage Toutes vos questions sur les scripts Perl en général. Avant de poster, veuillez consulter les FAQs perl, les cours Perl, les critiques de livres et les sources Perl.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 26/05/2007, 14h52   #1
Jedai
Expert Confirmé Sénior
 
Avatar de Jedai
 
Étudiant
Inscription : avril 2003
Messages : 6 068
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2003
Messages : 6 068
Points : 8 209
Points : 8 209
Envoyer un message via Yahoo à Jedai
Par défaut Débutants ou expérimentés : Comment écrire du bon code en Perl

Version courte :
  • Mettez
    Code Perl :
    1
    2
    3
    #!/usr/bin/env perl
    use strict;
    use warnings;
    au début de tous vos scripts.
  • Indentez proprement, ou demandez à perltidy de le faire pour vous.
    Code Shell :
    perltidy -b mon_script.pl
  • Eventuellement demandez à perlcritic de commentez votre code, vous n'êtes pas obligé de corriger tout ce qu'il vous dit, mais ce sera déjà un bon point de départ.
  • Utilisez les modules du CPAN ! Ce conseil vaut doublement pour les modules du CORE (qui viennent en standard avec Perl) excepté Switch.
  • N'utilisez pas les modules pour ce que vous pouvez faire en 2 lignes !
  • Utilisez les hashs, pas les tableaux, lorsque les données ont un index textuel évident pour votre utilisation des dites données dans votre script.

Bien sûr les conseils habituels à la programmation en n'importe quel langage s'appliquent :
  • Donnez des noms significatifs à vos variables ! Ne basez pas vos noms sur le type du contenu, mais sur son utilisation, sa provenance et sa destination.
  • Adoptez des conventions pour nommer vos variables et fonctions : en Perl la convention la plus répandu est d'utiliser des underscores "_" entre les mots, et de commencer les noms de fonctions par un verbe, mais l'important est que vous (et votre équipe) adoptiez une convention et vous y teniez, pas laquelle vous adoptez.
  • Découpez votre code en fonctions : DRY, Don't Repeat Yourself (Ne vous répétez pas !).
  • Découpez votre application en modules.
  • N'utilisez pas goto (sauf la version "goto fonction" spécifique au Perl, si vous savez ce que vous faites).
  • N'utilisez les variables globales que contraints et forcés ou pour des variables de configuration. Déclarez vos variables avec my() !


Version longue (aka "Les explications") :
La devise de Perl est TIMTOWDI, c'est-à-dire "There Is More Than One Way To Do It", en français : "Il y a plus d'une façon de le faire !".
Et effectivement Perl est un langage très flexible et puissant dans lequel vous pouvez adopter une multitude de méthodes différentes pour parvenir au même résultat.
Malheureusement, cela ne signifie pas que toutes les méthodes sont également viables, également efficaces, ou également faciles à entretenir ou lisibles...

Dans ce topic, je vais donc indiquer quelques points qui me semblent importants pour obtenir un résultat potable. Ce sujet est destiné aussi bien aux novices qu'aux expérimentés (je ne dirais pas aux experts, il n'y a pas beaucoup d'"experts" en Perl, et à mon avis ceux qui le sont doivent déjà savoir tout ce que je vais dire).

Le pragma "strict"

Qu'est-ce qu'un pragma ? C'est une instruction au compilateur/interpréteur qui modifie le comportement du langage sur une portée limitée. En Perl les pragmas sont chargés avec "use" ou déchargés avec "no", leur nom est tout en minuscule, contrairement aux noms de modules qui par convention doivent commencer par une majuscule.

Le pragma "strict" interdit l'usage d'un certains nombre de constructions normalement valables en Perl mais qui sont responsables de la plupart des erreurs basiques que peuvent rencontrer un novice, voire parfois un expert.
Pourquoi ces constructions ne sont-elles pas simplement supprimés du langage si elles sont si dangereuse me demanderez vous. Pour trois raisons :
  1. Le poids de l'histoire : Perl est un "vieux" langage, qui a commencé ses jours comme une simple glue Unix, alors que les shells étaient encore plus rudimentaires qu'aujourd'hui, il a retenu certains des défauts des shells de l'époque, défauts peu important pour un petit script de quelques lignes, beaucoup plus pour un programme constitué d'une vingtaines de modules... Mais l'une des fiertés de Perl est sa compatibilité en arrière dans le temps (backward compatibility), autrement dit sa capacité à faire tourner des scripts vieux de 10 ans sans modifications. Ce trait est assez rare pour le type de langage que Perl représente et il y réussit effectivement de façon impressionnante.
  2. L'utilité de ces constructions : en effet certaines de ces constructions peuvent se révéler utiles dans des cas très particuliers et pour faire des choses relevant de la magie noire. Mais ceci ne vous concerne que si vous avez l'habitude de mettre des modules complexes sur le CPAN, qui touchent au comportement même de Perl ou ce genre de chose.
  3. Dans un très petit script (ne dépassant pas dix lignes à mon avis, mais d'autres seront plus larges dans leur appréciation) ou un uniligne utiliser ces constructions interdites ne prête pas vraiment à conséquences et se les interdire alourdirait inutilement le programme.

Mais quels sont donc les effets concrets de strict ? Sans rentrer dans le détail, les principaux effets sont l'obligation de déclarer toutes ses nouvelles variables (avec my() pour les variables lexicales, our() pour les variables globales de paquetage), l'interdiction des mots "nus" (barewords, autrement dit, sans 'strict' Perl interprète tout mot isolé qu'il ne reconnait pas (pas un nom de fonction ou de HANDLE de fichier) comme une chaîne de caractères), et l'interdiction des références symboliques (l'utilisation d'une chaîne de caractère variable comme nom de variable).

Le pragma "warnings"

A partir de Perl 5.6 vous pouvez utiliser ce pragma en remplacement de l'option en ligne de commande -w (qu'on pouvait également indiquer sur la ligne de shebang d'un script). Il active les avertissements de Perl, qui vous indiquent les constructions douteuses ou ressemblant à des erreurs classiques dans votre code, à l'exécution comme à la compilation. Il ne s'agira pas toujours d'erreurs réelles, mais souvent un meilleur style de programmation peut faire disparaître ces avertissements, et dans les rares cas ou vous vous estimez justifié dans votre utilisation, un autre avantage du pragma warnings apparaîtra : vous pouvez le désactivez sélectivement sur une portion de code donnée et pour certains types d'avertissements précisément, lisez "perldoc perllexwarn" pour une explication en profondeur des avantages du pragma sur l'option -w.

Perl::Tidy

Le module Perl::Tidy et l'utilitaire perltidy qui vient avec ce module permettent de reformater aisément son code Perl, par exemple pour le mettre en conformité avec une norme d'entreprise ou un format que vous préférez à celui employé dans le code d'origine. Le formatage est complètement configurable et vous pouvez ainsi façonner le résultat exactement à votre goût. Indispensable !!

Perl::Critic

Perl::Critic et l'utilitaire perlcritic associé critique votre code selon un certain nombre de règles de bonne pratique décrites sous forme de module, dont beaucoup sont distribuées avec Perl::Critic (mais pas toutes), vous pouvez configurer exactement lesquelles prendre en compte (en plus du système de "niveau de sévérité" intégré à Perl::Critic) ou même en écrire de nouvelle.
En complément de cela si vous avez le temps (ou les sous), lisez "Perl Best Practices" ou sa traduction française "De l'art de programmer en Perl", excellent bouquin, qui se lit facilement, ( mais un peu cher ) et qui a servi de base à perlcritic.

Les modules et le CPAN

Ne réinventez pas la roue : surtout si vous êtes débutant (et que vous n'êtes pas en train de coder dans un but pédagogique), le code que vous produirez sera sans doute moins bon, moins robuste, moins efficace que le module du CPAN correspondant, et en plus il sera plus long à réécrire. Pensez toujours au CPAN, faites vos recherches dessus avec le site officiel ou le CPAN pour Win32 (qui vous indiquera où trouver vos paquetages ppm).

Ce qui ne veut pas dire que votre programme doit ressembler à une collection de modules du CPAN ! N'utilisez pas un module pour une seule fonction facilement refaites en quelques lignes par vous même (n'oubliez pas néanmoins que parfois la fonction du module a été écrite pour effectuer cette tâche bien plus rapidement et de façon bien plus robuste que votre pauvre petit remplacement). Ceci ne vaut pas pour les modules du CORE, ils sont disponibles partout (ou presque, utilisez Module::CoreList pour en avoir le coeur net) et sont la plupart du temps très bien codés donc n'hésitez surtout pas à les utiliser (sauf Switch, oubliez cette abomination !! Si vous voulez un switch..case en Perl, utilisez Perl5.10 qui devrait sortir cette année (2007) et offrir un très bon switch intégré. Les hashs sont souvent également une excellente alternative à la plupart des usages de switch..case).

Il y a également le cas où vous n'êtes pas tout à fait satisfait des modules disponibles sur le CPAN, n'hésitez pas alors à vous lancer dans la création d'un nouveau module (si vous êtes un programmeur suffisamment expérimenté), c'est ainsi qu'on fait progresser les choses ! Vous pouvez également proposer un patch à l'auteur d'un des modules du CPAN : s'il améliore les choses, ne brise pas la compatibilité arrière et relève vraiment du module, il sera très certainement accepté.

--
Jedaï
Jedai est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/03/2008, 10h05   #2
danyII
Invité régulier
 
Inscription : mars 2008
Messages : 16
Détails du profil
Informations personnelles :
Âge : 50
Localisation : Belgique

Informations forums :
Inscription : mars 2008
Messages : 16
Points : 6
Points : 6
Par défaut "Découpez votre code en fonctions" oui mais...

Bonjour,
En lisant votre article, il me vient une foule de questions que je résumerais en une grande question "bateau"... Qu'en est-il du temps d'exécution? Oui, il faut découper son script en sous-programmes, en modules, etc. Mais jusqu'à quel point? Je me souviens d'un script php que j'avais encodé comme un cochon, répetant les mêmes lignes de codes des dizaines et dizaines de fois . Lorsque j'ai entrepris de nettoyer ce script, certes j'ai réduis mon code de plus de 800 lignes en moins de 120 mais le temps d'exécution avait plus que doublé. Qu'en est-il avec Perl?
danyII est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/03/2008, 17h17   #3
Jedai
Expert Confirmé Sénior
 
Avatar de Jedai
 
Étudiant
Inscription : avril 2003
Messages : 6 068
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2003
Messages : 6 068
Points : 8 209
Points : 8 209
Envoyer un message via Yahoo à Jedai
Le degré exact d'abstraction que vous voulez atteindre est à déterminer par vous même. Néanmoins les avantages du découpage en fonctions sont énormes : maintenabilité énormément améliorée (lisibilité plus grande + mise à jour en un seul point plutôt qu'éparpillée dans les fichiers), risque de bugs décru, extension facile...

Un code de 800 lignes n'est pas grand chose encore, mais vous l'avez réduit d'un facteur 7 à peu près, et le facteur de réduction a tendance à augmenter plutôt que diminuer avec la taille du programme. A grande échelle, le découpage en fonction fait la différence entre un bourbier inutilisable et un programme vivant et évolutif.

Le doublement du temps d'exécution me semble un peu excessif, il est possible que votre design n'ait pas été trop bien pensé (si vous vous êtes contenté de regrouper les morceaux de code similaires). Mais même ainsi, il me semble acceptable, vu que de toute façon, en Perl comme en PHP, la performance n'est pas notre but premier (sinon autant coder en Assembleur (ou plus sérieusement, si vous cherchez un compromis entre performance et puissance, intéressez vous aux langages fonctionnels) ).

Je rappelle également que le découpage peut faciliter l'amélioration des performances par la suite : le profiling est plus facile, la réduction des goulets d'étranglement plus ciblée.

--
Jedaï
Jedai est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/08/2010, 22h23   #4
djibril
Responsable Perl et Outils

 
Avatar de djibril
 
Homme
Inscription : avril 2004
Messages : 13 535
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 33
Localisation : France

Informations forums :
Inscription : avril 2004
Messages : 13 535
Points : 31 723
Points : 31 723
La question Débutants ou expérimentés : Comment écrire du bon code en Perl à été rajoutés dans la FAQ dans la section divers.
__________________
Pas de questions technique par messagerie privée (lisez les règles du forum Perl) et pour les nouveaux !
djibril est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/03/2011, 13h58   #5
Ar3s.
Futur Membre du Club
 
Inscription : juin 2009
Messages : 25
Détails du profil
Informations forums :
Inscription : juin 2009
Messages : 25
Points : 18
Points : 18
Citation:
Envoyé par Jedai Voir le message
Version courte :
  • Utilisez les hashs, pas les tableaux, lorsque les données ont un index textuel évident pour votre utilisation des dites données dans votre script.

Version longue (aka "Les explications") :
  • Néant concernant le sujet précédemment cité
Et pourtant (pourtant) c'est bien le sujet qui me turlupine ...
Après avoir croisé et employé un certain nombre de langages et de paradigmes différents, je me suis dernièrement retrouvé face à Perl et la nécessité (pour diverses raisons) de devoir m'en servir et l'apprendre.

Ce langage m'a l'air, somme toute, intéressant et, sur certains aspects, élégant.

Par contre un point me taraude :

On me conseil partout d'employer des %Hash au lieux des @Arrays ...
Il semble (et c'est ce qui ressort souvent) que les %Hash en perl permettraient des insertions/suppressions/lecture en O(1).
Seulement voila, dans ma pauvre petite tête j'avais tendance à penser qu'on aurait plutôt un O(Log(n)) ...

Les %Hash sont ils en perl (je le crains) des sortes de tables creuses sur un modèle de ce genre :
Code :
1
2
3
4
5
6
7
8
9
===================
*** X cases vides
[Hash(clé3)] val3
*** Y cases vides
[Hash(clé1)] val1
*** Z cases vides
[Hash(clé2)] val2
*** encore et toujours des cases vides
===================
Ceci expliquerait que les Tables associatives ne soit pas "ordonnés" car rangés par Hash de leurs clés ...

Ou est-ce une autre méthode encore plus astucieuse (car moins consomatrice en espace)
Ar3s. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/03/2011, 15h26   #6
Dimitry.e
Membre confirmé
 
Avatar de Dimitry.e
 
Dimitry Ernot
Consultant télécommunications & réseaux intelligents
Inscription : janvier 2011
Messages : 184
Détails du profil
Informations personnelles :
Nom : Dimitry Ernot
Âge : 26

Informations professionnelles :
Activité : Consultant télécommunications & réseaux intelligents

Informations forums :
Inscription : janvier 2011
Messages : 184
Points : 286
Points : 286
Je ne sais pas comment fonctionnent en interne les tables de hachages de Perl.

Mais je peux t'en donner le fonctionnement général :
Une table de hachage est une structure de données complexe (souvent un arbre, un tableau de listes chaînées...). Elle a la particularité d'accéder aux données au travers d'une fonction de hachage (un peu comme MD5) qui dépend fortement du type de structure servant de clé.
Cette fonction calcule un indice ( souvent numérique) plus ou moins unique (on ne peut que rarement garantir l'absence de collisions). De cet indice, tu peux retrouver la donnée voulue ou insérer une nouvelle entrée.
Donc ce n'est pas la clé en elle-même qui te permet de retrouver la données mais son hachage.
Dimitry.e est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 20h46.


 
 
 
 
Partenaires

Hébergement Web