我们一直在使用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
使用,它可能就足够了.
是否有类似的东西,或者我应该从头开始?谢谢
目前没有任何东西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 /;
Run Code Online (Sandbox Code Playgroud)
(具有任何分隔符为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;
Run Code Online (Sandbox Code Playgroud)
用这个代码
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;
Run Code Online (Sandbox Code Playgroud)
从中生成此输出 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)
Run Code Online (Sandbox Code Playgroud)