Perl Language Utiliser Perl :: Critic


Exemple

Si vous souhaitez commencer à implémenter les meilleures pratiques, pour vous ou votre équipe, Perl :: Critic est le meilleur endroit pour commencer. Le module est basé sur le livre Perl Best Practices de Damien Conway et fait un assez bon travail pour implémenter les suggestions qui y sont faites.

Note: je devrais mentionner (et Conway lui-même dit dans le livre) que ce sont des suggestions. J'ai trouvé que le livre fournit un raisonnement solide dans la plupart des cas, bien que je ne sois certainement pas d'accord avec tous. La chose importante à retenir est que, quelles que soient les pratiques que vous décidez d’adopter, vous restez cohérent. Plus votre code est prévisible, plus il sera facile à maintenir.

Vous pouvez également essayer Perl :: Critic via votre navigateur sur perlcritic.com .

Installation

cpan Perl::Critic

Cela installera le jeu de règles de base et un script perlcritic pouvant être appelé à partir de la ligne de commande.


Utilisation de base

Le document CPAN pour perlcritic contient une documentation complète. Je ne vais donc que passer en revue les cas d'utilisation les plus courants pour vous lancer. L'utilisation de base consiste simplement à appeler perlcritic sur le fichier:

 perlcritic -1 /path/to/script.pl

perlcritic fonctionne aussi bien sur les scripts que sur les modules. Le -1 fait référence au niveau de gravité des règles que vous souhaitez exécuter sur le script. Il y a cinq niveaux qui correspondent à combien Perl :: Critic va séparer votre code.

-5 est le plus doux et avertira uniquement des problèmes potentiellement dangereux qui pourraient entraîner des résultats inattendus. -1 est le plus brutal et se plaindra des choses aussi petites que votre code soit ordonné ou non. D'après mon expérience, garder le code conforme au niveau 3 est suffisant pour rester hors de danger sans devenir trop discret.

Par défaut, les échecs répertorient la raison et la gravité de la règle sur:

perlcritic -3 --verbose 8 /path/to/script.pl

Debugging module loaded at line 16, column 1.  You've loaded Data::Dumper, which probably shouln't be loaded in production.  (Severity: 4)
Private subroutine/method '_sub_name' declared but not used at line 58, column 1.  Eliminate dead code.  (Severity: 3)
Backtick operator used at line 230, column 37.  Use IPC::Open3 instead.  (Severity: 3)
Backtick operator used at line 327, column 22.  Use IPC::Open3 instead.  (Severity: 3)

Affichage des politiques

Vous pouvez rapidement voir quelles règles sont déclenchées et pourquoi en utilisant l'option --verbose de perlcritic :

Si vous définissez le niveau sur 8, vous verrez la règle qui a déclenché un avertissement:

perlcritic -3 --verbose 8 /path/to/script.pl

[Bangs::ProhibitDebuggingModules] Debugging module loaded at line 16, column 1.  (Severity: 4)
[Subroutines::ProhibitUnusedPrivateSubroutines] Private subroutine/method '_sub_name' declared but not used at line 58, column 1.  (Severity: 3)
[InputOutput::ProhibitBacktickOperators] Backtick operator used at line 230, column 37.  (Severity: 3)
[InputOutput::ProhibitBacktickOperators] Backtick operator used at line 327, column 22.  (Severity: 3)

Alors qu'un niveau de 11 affichera les raisons spécifiques pour lesquelles la règle existe:

perlcritic -3 --verbose 11 /path/to/script.pl

Debugging module loaded at line 16, near 'use Data::Dumper;'.
  Bangs::ProhibitDebuggingModules (Severity: 4)
    This policy prohibits loading common debugging modules like the
    Data::Dumper manpage.

    While such modules are incredibly useful during development and
    debugging, they should probably not be loaded in production use. If this
    policy is violated, it probably means you forgot to remove a `use
    Data::Dumper;' line that you had added when you were debugging.
Private subroutine/method '_svn_revisions_differ' declared but not used at line 58, near 'sub _sub_name {'.
  Subroutines::ProhibitUnusedPrivateSubroutines (Severity: 3)
    By convention Perl authors (like authors in many other languages)
    indicate private methods and variables by inserting a leading underscore
    before the identifier. This policy catches such subroutines which are
    not used in the file which declares them.

    This module defines a 'use' of a subroutine as a subroutine or method
    call to it (other than from inside the subroutine itself), a reference
    to it (i.e. `my $foo = \&_foo'), a `goto' to it outside the subroutine
    itself (i.e. `goto &_foo'), or the use of the subroutine's name as an
    even-numbered argument to `use overload'.
Backtick operator used at line 230, near 'my $filesystem_diff = join q{}, `diff $trunk_checkout $staging_checkout`;'.
  InputOutput::ProhibitBacktickOperators (Severity: 3)
    Backticks are super-convenient, especially for CGI programs, but I find
    that they make a lot of noise by filling up STDERR with messages when
    they fail. I think its better to use IPC::Open3 to trap all the output
    and let the application decide what to do with it.

        use IPC::Open3 'open3';
        $SIG{CHLD} = 'IGNORE';

        @output = `some_command`;                      #not ok

        my ($writer, $reader, $err);
        open3($writer, $reader, $err, 'some_command'); #ok;
        @output = <$reader>;  #Output here
        @errors = <$err>;     #Errors here, instead of the console
Backtick operator used at line 327, near 'my $output = `$cmd`;'.
  InputOutput::ProhibitBacktickOperators (Severity: 3)
    Backticks are super-convenient, especially for CGI programs, but I find
    that they make a lot of noise by filling up STDERR with messages when
    they fail. I think its better to use IPC::Open3 to trap all the output
    and let the application decide what to do with it.

        use IPC::Open3 'open3';
        $SIG{CHLD} = 'IGNORE';

        @output = `some_command`;                      #not ok

        my ($writer, $reader, $err);
        open3($writer, $reader, $err, 'some_command'); #ok;
        @output = <$reader>;  #Output here
        @errors = <$err>;     #Errors here, instead of the console

Code ignorant

Il y aura des moments où vous ne pouvez pas vous conformer à une politique Perl :: Critic. Dans ces cas, vous pouvez placer des commentaires spéciaux, " ## use Critiques () " et " ## non critique " autour de votre code pour que Perl :: Critic les ignore. Ajoutez simplement les règles que vous souhaitez ignorer entre parenthèses (les multiples peuvent être séparés par une virgule).

##no critic qw(InputOutput::ProhibitBacktickOperator)
my $filesystem_diff = join q{}, `diff $trunk_checkout $staging_checkout`;
## use critic

Veillez à envelopper le bloc de code entier ou Critic peut ne pas reconnaître l'instruction ignore.

## no critic (Subroutines::ProhibitExcessComplexity)
sub no_time_to_refactor_this {
    ...
}
## use critic

Notez que certaines stratégies sont exécutées au niveau du document et ne peuvent pas être exemptées de cette manière. Cependant, ils peuvent être désactivés ...


Créer des exceptions permanentes

L'utilisation de ## aucun critique () est bien, mais lorsque vous commencez à adopter des normes de codage, vous voudrez probablement faire des exceptions permanentes à certaines règles. Vous pouvez le faire en créant un fichier de configuration .perlcriticrc .

Ce fichier vous permettra de personnaliser non seulement les stratégies exécutées, mais également leur mode d’exécution. Son utilisation est aussi simple que de placer le fichier dans votre répertoire personnel (sous Linux, ne sachant pas si c'est le même endroit sous Windows). Vous pouvez également spécifier le fichier de configuration lors de l'exécution de la commande à l'aide de l'option --profile :

perlcritic -1 --profile=/path/to/.perlcriticrc /path/to/script.pl

Encore une fois, la page CPAN perlcritique contient une liste complète de ces options. Je vais lister quelques exemples de mon propre fichier de configuration:

Appliquer les paramètres de base:

#very very harsh
severity = 1
color-severity-medium = bold yellow
color-severity-low = yellow
color-severity-lowest = bold blue

Désactiver une règle (notez le tiret devant le nom de la stratégie):

# do not require version control numbers
[-Miscellanea::RequireRcsKeywords]

# pod spelling is too over-zealous, disabling
[-Documentation::PodSpelling]

Modifier une règle:

# do not require checking for print failure ( false positives for printing to stdout, not filehandle )
[InputOutput::RequireCheckedSyscalls]
    functions = open close

# Allow specific unused subroutines for moose builders
[Subroutines::ProhibitUnusedPrivateSubroutines]
private_name_regex = _(?!build_)\w+

Conclusion

Utilisé correctement, Perl :: Critic peut être un outil inestimable pour aider les équipes à maintenir la cohérence et la maintenance de leur codage, quelles que soient les meilleures politiques que vous utilisez.