11

Perl::Criticここでは、コード規則を適用するためにここで使用しています。最近/tmp、関数が原因でディレクトリがいっぱいになるという問題が発生しましたTemp::File::tempdirtempdirPerlプロセスが終了するとクリーンアップしますが、バックエンド全体がPerlプロセスであるため、これはサーバー自体が再起動されたときにのみ発生します(それほど頻繁ではありません)。newdir将来的には、オブジェクトがスコープ外になるとすぐにクリーンアップするオブジェクトメソッドを使用することを開発者に推奨したいと思います。

基本的に、コーディング規約違反としてマークしようとしていますTemp::File::tempdirが、CPANで同様のルールを見つけることができないようです。誤検知を導入せずに動的型付け言語でこれを実施するのは難しいことを理解していますが、過去に別の非推奨の関数で同様の問題が発生したことがあると思います。トリッキーなケースをすべてキャッチすることも期待しているわけではなく、の最も明白な使用法だけをキャッチすることを期待していますTemp::File::tempdirtempdirアイデアは、批評家をだますためのすべての試みを捕らえるのではなく、いつnewdir仕事をすることができるかを誤って使用することを思いとどまらせることです(開発者はいつでも使用できます## no critic)。tempdirが定義されている場合use Temp::File(できれば他に何も再定義されていないことを確認するtempdir)、いつ使用されているかについて文句を言うだけで十分でしょうTemp::File::tempdir

すでに似たようなものはありますか、それとも最初から始めるべきですか?ありがとう

4

1 に答える 1

9

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)
于 2012-12-04T06:41:58.270 に答える