Perl Language
Best practices
Zoeken…
Perl gebruiken :: Critic
Als u wilt beginnen met het implementeren van best practices, voor uzelf of uw team, dan is Perl :: Critic de beste plaats om te beginnen. De module is gebaseerd op het Perl Best Practices- boek van Damien Conway en voert de daarin gemaakte suggesties redelijk goed uit.
Opmerking: ik moet vermelden (en Conway zelf zegt in het boek) dat dit suggesties zijn. Ik heb gemerkt dat het boek in de meeste gevallen een goede redenering biedt, hoewel ik het zeker niet met iedereen eens ben. Het belangrijkste om te onthouden is dat, welke praktijken u ook besluit te nemen, u consistent blijft. Hoe voorspelbaarder uw code is, hoe gemakkelijker deze te onderhouden is.
Je kunt Perl :: Critic ook uitproberen via je browser op perlcritic.com .
Installatie
cpan Perl::Critic
Hiermee worden de basisregelset en een perlcritisch script geïnstalleerd dat vanaf de opdrachtregel kan worden aangeroepen.
Basisgebruik
Het CPAN-document voor perlcritic bevat volledige documentatie, dus ik zal alleen de meest voorkomende use-cases doornemen om u op weg te helpen. Het basisgebruik is om perlcritic eenvoudig in het bestand aan te roepen:
perlcritic -1 /path/to/script.pl
perlcritic werkt zowel op scripts als op modules. De -1 verwijst naar het ernstniveau van de regels die u tegen het script wilt uitvoeren. Er zijn vijf niveaus die overeenkomen met hoeveel Perl :: Critic uw code uit elkaar haalt.
-5 is het zachtst en waarschuwt alleen voor potentieel gevaarlijke problemen die onverwachte resultaten kunnen veroorzaken. -1 is de meest brutale en zal klagen over dingen zo klein als je code is netjes of niet. In mijn ervaring is het voldoende om code compatibel te houden met niveau 3 om buiten gevaar te blijven zonder te persnickety te worden.
Standaard worden bij eventuele fouten de reden en ernst vermeld waarop de regel wordt geactiveerd:
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)
Beleid bekijken
U kunt snel zien welke regels worden geactiveerd en waarom door de optie --verbose van perlcritic te gebruiken:
Als u het niveau instelt op 8, wordt de regel weergegeven die een waarschuwing heeft geactiveerd:
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)
Hoewel een niveau van 11 de specifieke redenen zal tonen waarom de regel bestaat:
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 negeren
Er zullen momenten zijn waarop u niet kunt voldoen aan een Perl :: Critic-beleid. In die gevallen kunt u speciale opmerkingen, " ## use critical () " en " ## no critical ", om uw code heen laten lopen zodat Perl :: Critic ze negeert. Voeg eenvoudig de regels toe die u wilt negeren tussen haakjes (veelvouden kunnen worden gescheiden door een komma).
##no critic qw(InputOutput::ProhibitBacktickOperator)
my $filesystem_diff = join q{}, `diff $trunk_checkout $staging_checkout`;
## use critic
Zorg ervoor dat u het volledige codeblok wikkelt, anders herkent Critic de instructie negeren niet.
## no critic (Subroutines::ProhibitExcessComplexity)
sub no_time_to_refactor_this {
...
}
## use critic
Merk op dat er bepaalde beleidsregels zijn die op documentniveau worden uitgevoerd en op deze manier niet kunnen worden vrijgesteld. Ze kunnen echter worden uitgeschakeld ...
Permanente uitzonderingen maken
Het gebruik van ## geen criticus () is leuk, maar als je coderingsstandaarden begint te gebruiken, wil je waarschijnlijk permanente uitzonderingen maken op bepaalde regels. U kunt dit doen door een .perlcriticrc- configuratiebestand te maken.
Met dit bestand kunt u niet alleen aanpassen welk beleid wordt uitgevoerd, maar ook hoe dit wordt uitgevoerd. Het gebruik ervan is net zo eenvoudig als het plaatsen van het bestand in uw basismap (in Linux, niet zeker of het op dezelfde plaats staat in Windows). Of u kunt het configuratiebestand opgeven bij het uitvoeren van de opdracht met de optie --profile :
perlcritic -1 --profile=/path/to/.perlcriticrc /path/to/script.pl
Nogmaals, de perlcritische CPAN-pagina bevat een volledige lijst van deze opties. Ik zal enkele voorbeelden uit mijn eigen configuratiebestand opsommen:
Basisinstellingen toepassen:
#very very harsh
severity = 1
color-severity-medium = bold yellow
color-severity-low = yellow
color-severity-lowest = bold blue
Schakel een regel uit (let op het streepje voor de beleidsnaam):
# do not require version control numbers
[-Miscellanea::RequireRcsKeywords]
# pod spelling is too over-zealous, disabling
[-Documentation::PodSpelling]
Een regel wijzigen:
# 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+
Conclusie
Correct gebruikt, kan Perl :: Critic een hulpmiddel van onschatbare waarde zijn om teams te helpen hun codering consistent en gemakkelijk te onderhouden te houden, ongeacht welk best practices-beleid u hanteert.