Perl:: Критик правило "Не используйте этот метод"
Мы использовали Perl::Critic
здесь, на работе, чтобы обеспечить соблюдение наших соглашений кода. Недавно мы столкнулись с проблемами /tmp
каталог заполняется из-за Temp::File::tempdir
функция. tempdir
очищается, когда завершается процесс Perl, но поскольку весь наш бэкэнд представляет собой процесс Perl, это происходит только тогда, когда сам сервер перезапускается (не очень часто). Мы хотим призвать разработчиков использовать newdir
метод объекта в будущем, который убирает за собой, как только объект выходит из области видимости.
По сути, мы пытаемся отметить Temp::File::tempdir
как нарушение соглашения о коде, но я не могу найти какое-либо правило, которое было бы похоже на CPAN. Я понимаю, что это трудно реализовать на языке с динамической типизацией без введения ложных срабатываний, но я ожидаю, что кто-то сталкивался с подобной проблемой в прошлом с другой устаревшей функцией. Мы не ожидаем отловить все сложные случаи, только самые очевидные случаи использования Temp::File::tempdir
, Идея состоит в том, чтобы препятствовать случайному использованию tempdir
когда newdir
может сделать работу, чтобы не уловить все попытки обмануть критика (разработчик всегда мог просто использовать ## no critic
). Вероятно, было бы достаточно, чтобы жаловаться, когда tempdir
используется, если use Temp::File
определяется (желательно проверять, что ничего не переопределяет tempdir
) и когда Temp::File::tempdir
используется.
Уже есть что-то подобное, или я должен начать с нуля? Спасибо
1 ответ
Там нет ничего в Perl::Critic
в настоящее время, чтобы предоставить то, что вам нужно, но вполне возможно добавить политику, чтобы сделать что-то подобное. к несчастью PPI
недостаточно для того, чтобы правильно определить, что делает каждый токен в программе, поэтому он требует больше кода, чем мог бы.
Эта программа проверяет наличие use File::Temp
заявление, которое пытается импортировать tempdir
используя любой из
use File::Temp 'tempdir';
use File::Temp q(tempdir);
use File::Temp "tempdir";
use File::Temp qq(tempdir);
use File::Temp qw/ tempdir /;
(с любым разделителем для q
, qq
, а также qw
формы). Он также проверяет наличие PPI::Token::Word
узел, который выглядит как вызов функции и равен File::Temp::tempdir
,
package Perl::Critic::Policy::Prohibit_tempdir;
use strict;
use warnings;
use Perl::Critic::Utils qw{ is_function_call :severities };
use Scalar::Util 'blessed';
use base 'Perl::Critic::Policy';
my $DESC = 'Temp::File::tempdir function';
my $EXPL = 'The tempdir function from Temp::File is deprecated. Use newdir method instead';
sub default_severity { $SEVERITY_HIGH };
sub applies_to{ qw/ PPI::Statement::Include PPI::Token::Word / }
sub violates {
my ($self, $elem) = @_;
if ($elem->isa('PPI::Statement::Include')) {
return unless $elem->type eq 'use';
my $module = $elem->module;
return unless $module and $module eq 'File::Temp';
for my $kid ($elem->children) {
next unless blessed($kid) =~ /^PPI::Token::Quote/;
if ($kid->can('string') and $kid->string eq 'tempdir'
or $kid->can('literal') and grep $_ eq 'tempdir', $kid->literal) {
return $self->violation($DESC, $EXPL, $elem);
}
}
}
else {
if (is_function_call($elem) and $elem eq 'File::Temp::tempdir') {
return $self->violation($DESC, $EXPL, $elem);
}
}
return;
}
1;
с этим кодом
use strict;
use warnings;
use File::Temp 'tempdir';
use File::Temp "tempdir";
use File::Temp qw/ tempdir /;
my $dir = tempdir();
$dir = tempdir;
$dir = File::Temp::tempdir;
my $ft = File::Temp->new;
$dir = $ft->newdir;
генерирует этот вывод из perlcritic -4 test.pl
Code not contained in explicit package at line 1, column 1. Violates encapsulation. (Severity: 4)
Temp::File::tempdir function at line 4, column 1. The tempdir function from Temp::File is deprecated. Use newdir method instead. (Severity: 4)
Temp::File::tempdir function at line 5, column 1. The tempdir function from Temp::File is deprecated. Use newdir method instead. (Severity: 4)
Temp::File::tempdir function at line 6, column 1. The tempdir function from Temp::File is deprecated. Use newdir method instead. (Severity: 4)
Temp::File::tempdir function at line 10, column 8. The tempdir function from Temp::File is deprecated. Use newdir method instead. (Severity: 4)
Module does not end with "1;" at line 13, column 1. Must end with a recognizable true value. (Severity: 4)