2009-10-28 8 views
7

私はPerlコードベースを持っており、多くの冗長な機能があり、多くのファイルにまたがっています。Perlで冗長コードを特定して削除するにはどうすればよいですか?

コードベースでこれらの冗長な機能を識別する便利な方法はありますか? このために自分のコードベースを確認できる簡単なツールはありますか?

+1

「冗長」とは何を意味するのか正確にはわかりません。同じ仕事をしている複数のサブシステムについて話していますか?または決して呼び出されないサブシステムについて?または両方? – innaM

答えて

10

B::Xrefモジュールを使用して、相互参照レポートを生成できます。

+0

私はこのようなものを探していた... – someguy

3

これは便利ではないかもしれませんが、このための最良のツールはあなたの脳です。すべてのコードを読み、その相互関係を理解する。共通のパターンを見てみてください。その後、リファクタリング!

質問に「refactoring」とタグ付けしました。あなたは、この主題の下に提出されたこのサイトの興味深い資料を見つけることができます。

+5

私はストック室スタイルのリファクタが好きです。 1.コードをgitにチェックします。 2.たくさんのテストがあることを確認してください。 3.モジュール全体の名前を、使用できないものに変更します。 4.空のものを作成します。 5.テストが終了するまで関数をコピーして、リファクタリングします。 6.古いモジュールから機能をコピーする必要がない1ヶ月後に、それを取り外します。 –

+0

@Ether:あなたはリファクタリングについて正しいですが、最初に関数の場所を探す必要があります。 :) – someguy

0

Linuxの場合は、grepを使用して、コードベースのすべての関数のリストを作成できます。おそらくEtherが示唆していることを実行して、あなたがまだそれを理解していない場合はコードを実際に実行する必要があります。あなたはこのあまりにも重複を探すことができます

grep -r "sub " codebase/* > function_list 

はここでオーバー簡略化した例です。 PerlのOOP機能を使用している場合、この考え方はあまり効果的ではありません。

コード文書ツールNaturalDocsも言及する価値があります。これはあなたが進むのに役立ちます。

+10

Perlで作業しているなら、純粋なPerlバージョンの 'grep'である' ack'の使用を検討してくださいPerlのより強力な正規表現サポートを利用しています。 –

8

私は過去にこの問題を自分で解決しました。私はPPIを使ってサブルーチンを見つける素早く小さなプログラムを打ちました。これは、コードを少し正規化(空白を正規化し、コメントを削除)し、重複を報告します。合理的にうまくいく。 PPIはすべての重労働をします。

各ルーチンのすべての変数名を$ a、​​$ b、$ cに正規化して文字列に似たようにすることで、正規化を少しスマートにすることができます。あなたがどれくらい積極的であるかに依存します。

#!perl 

use strict; 
use warnings; 

use PPI; 

my %Seen; 

for my $file (@ARGV) { 
    my $doc = PPI::Document->new($file); 
    $doc->prune("PPI::Token::Comment");   # strip comments 

    my $subs = $doc->find('PPI::Statement::Sub'); 
    for my $sub (@$subs) { 
     my $code = $sub->block; 
     $code =~ s/\s+/ /;      # normalize whitespace 
     next if $code =~ /^{\s*}$/;    # ignore empty routines 

     if($Seen{$code}) { 
      printf "%s in $file is a duplicate of $Seen{$code}\n", $sub->name; 
     } 
     else { 
      $Seen{$code} = sprintf "%s in $file", $sub->name; 
     } 
    } 
} 
+0

ニース!しかし、なぜあなたは空のルーチンを無視する必要がありますか? – innaM

+1

目的は、冗長なコードを見つけ出すのではなく、その除去を助けることです。それは空のルーチンを報告することがちょうど混乱していたことをすぐに明らかにしました。 'sub foo {}'には何も問題ありません。 'my $ foo = $ EMPTY_STRING'と同じくらい愚かな代替の' * foo = \&DO_NOTHING'について考えると、それは意味をなさないでしょう。 – Schwern

関連する問題