2012-12-03 18 views
11

Kod kurallarımızı uygulamak için işyerinde Perl::Critic kullanıyoruz. Son zamanlarda, Temp::File::tempdir işlevi nedeniyle /tmp dizini doldu. Perl işlemi sona erdiğinde tempdir temizler, ancak tüm arka ucumuz Perl işlemi olduğundan, yalnızca sunucu yeniden başlatıldığında (çok sık değil) oluşur. Gelecekte geliştiricilerin newdir nesne yöntemini kullanmalarını teşvik etmek istiyoruz; bu, nesnenin kapsam dışına çıktığı anda kendini temizler.Perl :: Critic "Bu yöntemi kullanmayın" -type kuralı

Temel olarak, Temp::File::tempdir kod kural ihlali olarak işaretlemeye çalışıyoruz, ancak CPAN'da benzer olabilecek herhangi bir kural göremiyorum. Bunun yanlış pozitifleri ortaya koymadan dinamik olarak yazılan bir dilde zorlanmasının zor olduğunu anlıyorum, ama birilerinin geçmişte benzer bir sorunla karşılaştığını ve başka bir kullanımdan vazgeçilmiş bir işlev görmesini beklerim. Tüm zor durumları yakalamayı beklemiyoruz, sadece Temp::File::tempdir'un en belirgin kullanımları. Buradaki düşünce,'un işi yapabilmesi için tempdir'un yanlışlıkla kullanılmasını engellemektir, eleştirmeni kandırmak için tüm girişimleri yakalamamaktadır (geliştirici her zaman ## no critic'u kullanabilir).tanımlanmışsa tempdir kullanıldığında (tercihen tempdir yeniden tanımlıyorsa) ve Temp::File::tempdir kullanıldığında şikayet etmek yeterli olacaktır.

Zaten benzer bir şey var mı, yoksa sıfırdan başlamalı mıyım? Teşekkürler

+2

bu çıktı üretir. "ProhibitEvilModules" ve "ProhibitEvilVariables" politikaları yapılandırılabilir, ancak "ProhibitEvilMethods" var mı? – mob

cevap

9

Perl::Critic'da ihtiyacınız olanı sağlamak için şu anda herhangi bir şey yoktur, ancak bunun gibi bir şey yapmak için bir ilke eklemek oldukça olasıdır. Ne yazık ki, PPI, programdaki her belirteçin ne yaptığını doğru bir şekilde tanımlamak için kapsamlı değildir, bu yüzden daha fazla kodlama gerektirebilir.

(q, qq ve qw formları için herhangi sınırlayıcısıyla)

use File::Temp 'tempdir'; 
use File::Temp q(tempdir); 
use File::Temp "tempdir"; 
use File::Temp qq(tempdir); 
use File::Temp qw/ tempdir /; 

herhangi birini kullanarak tempdir içe çalışan bir use File::Temp deyimi Bu program denetler. Ayrıca, bir işlev çağrısı gibi görünen ve File::Temp::tempdir'a eşit olan PPI::Token::Word düğümünü de denetler. Bu kod

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; 

ile

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; 

meraklı 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) 
+0

Teşekkürler, bu neredeyse ihtiyaç duyduğumuz şeyi yapar, 8 ve 9 numaralı satırları yakalamaz, ancak bunu yapmak için onu değiştiririm ve muhtemelen daha genel olmasını sağlayın, böylece yöntemler modül başına belirtilebilir. biraz daha genel. –

+0

Sorunuzda anlattığınız yaklaşımı kullandım. Çizgiler 8 ve 9'dakiler gibi çağrılar, sadece 4, 5 veya 6 numaralı satırların bir örneği varsa derlenecektir, yani altprogram, çağrılmadan önce içe aktarılmalıdır. Mod birim adıyla tam olarak nitelenmeyen 'tempdir' çağrılarının tanımlanması ile ilgili sorun, PPI'nın barebordun görünüşü bağlamında çok yardımcı olmamasıdır. 'Perl :: Critic :: Utils' tarafından sağlanan' is_function_call' sınıflandırıcısı çok belirsizdir ve basitçe, bariyerin kontrol ettiği diğer dokuz olasılıktan herhangi biri olmadığı anlamına gelir. – Borodin

İlgili konular