Perl :: Critic“不要使用此方法”类型规则

时间:2012-12-03 21:01:08

标签: perl perl-critic

我们在这里一直在使用Perl::Critic来强制执行我们的代码约定。最近,由于/tmp功能导致Temp::File::tempdir目录被填满,我们遇到了问题。当Perl进程终止时,tempdir会清除,但由于我们的整个后端都是Perl进程,所以只有在服务器本身重新启动时才会发生(不常见)。我们希望鼓励开发人员在将来使用newdir对象方法,一旦对象超出范围,它就会自动清理。

基本上,我们试图将Temp::File::tempdir标记为违反代码约定,但我似乎无法找到任何类似于CPAN的规则。我知道这很难用动态类型的语言强制执行而不会引入误报,但我希望有人在过去遇到过类似的问题而另一个被弃用的函数。我们也不期望抓住所有棘手的案例,只是Temp::File::tempdir最明显的用法。我的想法是阻止在tempdir完成工作时意外使用newdir,而不是抓住所有欺骗批评者的企图(开发人员总是可以使用## no critic)。如果定义了tempdir,那么在使用use Temp::File时抱怨可能就足够了(最好检查没有其他内容重新定义tempdir)以及何时使用Temp::File::tempdir

是否已有相似之处,或者我应该从头开始?感谢

1 个答案:

答案 0 :(得分:9)

目前Perl::Critic中没有任何内容可以提供您所需要的内容,但很可能会添加一项策略来执行类似的操作。遗憾的是PPI并不全面,无法正确识别程序中每个令牌的作用,因此需要更多的编码。

此程序检查尝试使用

中的任何一个导入use File::Temp的{​​{1}}语句
tempdir

(包含use File::Temp 'tempdir'; use File::Temp q(tempdir); use File::Temp "tempdir"; use File::Temp qq(tempdir); use File::Temp qw/ tempdir /; qqq表单的任何分隔符。它还检查看起来像函数调用的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