Perl Language
Лучшие практики
Поиск…
Использование Perl :: Критика
Если вы хотите начать применять лучшие практики, для себя или своей команды, то Perl :: Critic - лучшее место для начала. Модуль основан на книге Perl Best Practices Дэмиена Конвей и довольно неплохо работает над воплощением предложений, сделанных в ней.
Примечание: я должен упомянуть (и сам Конвей говорит в книге), что это предложения. Я обнаружил, что в большинстве случаев книга содержит убедительные аргументы, хотя я, конечно, не согласен со всеми из них. Важно помнить, что, независимо от того, какую практику вы принимаете, вы остаетесь последовательными. Чем более предсказуемым будет ваш код, тем легче будет его поддерживать.
Вы также можете попробовать Perl :: Critic через свой браузер на perlcritic.com .
Монтаж
cpan Perl::Critic
Это установит базовый набор правил и perlcritic скрипт, который можно вызвать из командной строки.
Основное использование
Документ CPAN для perlcritic содержит полную документацию, поэтому я буду использовать только самые распространенные варианты использования, чтобы вы начали. Основное использование - просто вызвать perlcritic в файле:
perlcritic -1 /path/to/script.pl
perlcritic работает как на скриптах, так и на модулях. -1 относится к уровню серьезности правил, которые вы хотите запустить против скрипта. Существует пять уровней, которые соответствуют тому, насколько Perl :: Critic будет выделять ваш код.
-5 является самым нежным и будет предупреждать только о потенциально опасных проблемах, которые могут вызвать неожиданные результаты. -1 является самым жестоким и будет жаловаться на вещи размером с ваш код, аккуратный или нет. По моему опыту, соблюдение кода, соответствующего уровню 3, является достаточно хорошим, чтобы избежать опасности, не слишком мучаясь.
По умолчанию в любых отказах указывается причина и степень серьезности триггера правила:
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)
Просмотр политик
Вы можете быстро увидеть, какие правила запускаются и почему, используя опцию perlcritic --verbose :
Установка уровня до 8 покажет вам правило, вызвавшее предупреждение:
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)
Хотя уровень 11 покажет конкретные причины, по которым правило существует:
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
Игнорирование кода
Будут случаи, когда вы не можете выполнить политику Perl :: Critic. В таких случаях вы можете добавить специальные комментарии, « ## use crit () » и « ## no crit », вокруг вашего кода, чтобы заставить Perl :: Critic игнорировать их. Просто добавьте правила, которые вы хотите игнорировать в круглых скобках (кратные могут быть разделены запятой).
##no critic qw(InputOutput::ProhibitBacktickOperator)
my $filesystem_diff = join q{}, `diff $trunk_checkout $staging_checkout`;
## use critic
Обязательно оберните весь блок кода, или критик может не распознать инструкцию ignore.
## no critic (Subroutines::ProhibitExcessComplexity)
sub no_time_to_refactor_this {
...
}
## use critic
Обратите внимание, что существуют определенные политики, которые выполняются на уровне документа и не могут быть освобождены таким образом. Однако их можно отключить ...
Создание постоянных исключений
Использование ## no crit () хорошо, но по мере того, как вы начинаете применять стандарты кодирования, вы, вероятно, захотите сделать перманентные исключения для определенных правил. Вы можете сделать это, создав конфигурационный файл .perlcriticrc .
Этот файл позволит вам настроить не только те политики, которые выполняются, но и то, как они выполняются. Использование его так же просто, как размещение файла в вашем домашнем каталоге (в Linux, неуверенном, если это то же самое место в Windows). Или вы можете указать файл конфигурации при запуске команды с помощью опции -profile :
perlcritic -1 --profile=/path/to/.perlcriticrc /path/to/script.pl
Опять же, страница Perlcritic CPAN имеет полный список этих параметров. Я приведу несколько примеров из моего собственного файла конфигурации:
Применить основные настройки:
#very very harsh
severity = 1
color-severity-medium = bold yellow
color-severity-low = yellow
color-severity-lowest = bold blue
Отключите правило (обратите внимание на тире перед именем политики):
# do not require version control numbers
[-Miscellanea::RequireRcsKeywords]
# pod spelling is too over-zealous, disabling
[-Documentation::PodSpelling]
Изменение правила:
# 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+
Заключение
Правильно используемая Perl :: Critic может быть бесценным инструментом, помогающим командам сохранять свою кодировку согласованной и легко поддерживаемой, независимо от того, какую политику вы используете.