2009-10-28 11 views
7

Tengo una base de código Perl, y hay muchas funciones redundantes y están distribuidas en muchos archivos.¿Cómo puedo identificar y eliminar código redundante en Perl?

¿Existe alguna forma conveniente de identificar esas funciones redundantes en la base de código? ¿Hay alguna herramienta simple que pueda verificar mi código base para esto?

+1

No estoy exactamente seguro de lo que quieres decir cuando dices "redundante". ¿Estás hablando de múltiples subs que hacen el mismo trabajo? ¿O sobre submarinos que nunca se llaman? ¿O ambos? – innaM

Respuesta

10

podría utilizar el módulo de B::Xref para generar informes de referencias cruzadas.

+0

Estaba buscando algo como esto ... – someguy

3

Puede que no sea conveniente, pero la mejor herramienta para esto es tu cerebro. Repase todo el código y entienda sus interrelaciones. Intenta ver los patrones comunes. Entonces, refactor!

que lo ha insertado en cuestión con "refactoring". Puede encontrar material interesante en este sitio archivado bajo ese tema.

+5

Me gusta el refactor de estilo stock. 1. Verifique el código en git. 2. Asegúrate de tener muchas pruebas. 3. Cambie el nombre del módulo en su totalidad a algo inutilizable. 4. Crea uno vacío. 5. Copie las funciones hacia atrás, refactorizándolas sobre la marcha, hasta que las pruebas pasen nuevamente. 6. Después de un mes de no necesitar copiar funciones del módulo anterior, elimínelo. –

+0

@Ether: su razón sobre refactorización ... pero primero necesito para localizar las funciones .. :) – someguy

0

Si está en Linux podría usar grep para ayudarle a hacer la lista de todas las funciones de su código base. Probablemente necesites hacer lo que Ether sugiere y realmente revisar el código para entenderlo si aún no lo has hecho.

He aquí un exceso de simplificación ejemplo:

grep -r "sub " codebase/* > function_list 

Usted puede buscar duplicados de esta manera también. Esta idea puede ser menos efectiva si está usando la capacidad OOP de Perl.

También valdría la pena mencionar NaturalDocs, una herramienta de documentación de código. Esto te ayudará a seguir adelante.

+10

Si está trabajando con Perl, considere el uso de 'ack', una versión pura-Perl del' grep' que aprovecha el soporte de expresiones regulares más poderoso de Perl. –

8

Me he encontrado con este problema yo mismo en el pasado. Hice un pequeño y rápido programa que usa PPI para encontrar subrutinas. Normaliza el código un poco (espacio en blanco normalizado, comentarios eliminados) e informa cualquier duplicado. Funciona razonablemente bien. PPI hace todo el trabajo pesado.

usted podría hacer la normalización un poco más inteligente mediante la normalización de los nombres de las variables en cada rutina de $ a, $ b, $ c y tal vez hacer algo similar para las cadenas. Depende de qué tan agresivo quieras ser.

#!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

¡Agradable! Pero, ¿por qué necesitas ignorar las rutinas vacías? – innaM

+1

El propósito no es solo encontrar el código redundante sino ayudar a su eliminación. Rápidamente fue obvio, al correr, que informar las rutinas vacías era un desorden. No hay nada malo con 'sub foo {}'. Cuando piensas en la alternativa '* foo = \ & DO_NOTHING', que es tan tonta como' my $ foo = $ EMPTY_STRING', todo debería tener sentido. – Schwern

Cuestiones relacionadas