2009-10-28 94 views
7

我有一個Perl代碼庫,並且有很多冗餘功能,它們分佈在很多文件中。如何識別和刪除Perl中的冗餘代碼?

有沒有一種方便的方法來識別代碼庫中的冗餘功能? 是否有任何簡單的工具可以驗證我的代碼庫?

+1

我不完全確定你說「多餘」時的意思。你是否在談論所有做同樣工作的多個潛艇?或者關於從未被調用的潛艇?或兩者? – innaM 2009-10-28 09:13:01

回答

10

您可以使用B::Xref模塊生成交叉引用報告。

+0

我正在尋找這樣的東西... – someguy 2009-10-28 08:09:13

3

它可能不方便,但最好的工具是你的大腦。瀏覽所有代碼並理解其相互關係。嘗試看看常見的模式。然後,重構!

我用「refactoring」標記了您的問題。你可能會在這個主題下找到一些有趣的材料。

+5

我喜歡庫房風格的重構。 1.檢查代碼到git中。 2.確保你有很多測試。 3.將整個模塊重新命名爲不可用的東西。 4.創建一個空的。 5.將功能複製回去,隨時重構它們,直到測試再次通過。 6.在不需要複製舊模塊的功能一個月後,將其刪除。 – 2009-10-28 07:18:57

+0

@Ether:你對重構是正確的...但首先我需要找到函數.. :) – someguy 2009-10-28 08:10:41

0

如果您在Linux上,您可以使用grep來幫助您列出代碼庫中的所有功能。你可能需要做Ether建議的內容,並且如果你還沒有完全理解它,那麼你可以通過代碼去理解它。

這裏是一個過於簡單的例子:

grep -r "sub " codebase/* > function_list 

你可以找出重複的也是這樣的。如果你使用Perl的OOP功能,這個想法可能不太有效。

它也許值得一提的代碼文檔工具NaturalDocs。這會幫助你前進。

+10

如果你使用Perl,考慮使用'ack',一個純Perl版本的'grep'利用Perl更強大的正則表達式支持。 – 2009-10-28 05:58:37

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 2009-10-28 09:11:38

+1

目的不僅僅是爲了找到多餘的代碼,而是幫助刪除它。運行過程中很明顯,報告空白的例程很混亂。 'sub foo {}'沒有錯。當你考慮替代'* foo = \&DO_NOTHING'時,這與'my $ foo = $ EMPTY_STRING'一樣愚蠢,應該都是有道理的。 – Schwern 2009-10-28 22:53:20