Esiste uno strumento per l'estrazione di tutti, modulo e nomi delle funzioni di variabili da un file di modulo Perl?

StackOverflow https://stackoverflow.com/questions/1343630

  •  20-09-2019
  •  | 
  •  

Domanda

Le mie scuse se questo è un duplicato; Potrei non conoscere i termini adeguati per la ricerca.

Io sono incaricato di analizzare un file di modulo Perl (.pm), che è un frammento di un'applicazione più ampia. Esiste uno strumento, app, o uno script che semplicemente passare attraverso il codice e tirare fuori tutti i nomi di variabili, i nomi dei moduli, e chiamate di funzione? Ancora meglio sarebbe qualcosa che avrebbe identificare se è stato dichiarato all'interno di questo file o è qualcosa di esterno.

Se un tale strumento esiste? Ho solo il file, quindi questo non è qualcosa che posso eseguire -. Solo alcune analisi statica di base Credo

È stato utile?

Soluzione

Scopri il nuovo, ma ben consigliato Class::Sniff .

Dalla documentazione:

use Class::Sniff;
my $sniff = Class::Sniff->new({class => 'Some::class'});

my $num_methods = $sniff->methods;
my $num_classes = $sniff->classes;
my @methods     = $sniff->methods;
my @classes     = $sniff->classes;

{
  my $graph    = $sniff->graph;   # Graph::Easy
  my $graphviz = $graph->as_graphviz();

  open my $DOT, '|dot -Tpng -o graph.png' or die("Cannot open pipe to dot: $!");
  print $DOT $graphviz;
}

print $sniff->to_string;
my @unreachable = $sniff->unreachable;
foreach my $method (@unreachable) {
    print "$method\n";
}

Questo ti porterà la maggior parte della strada. Alcuni variables, a seconda del campo di applicazione, potrebbe non essere disponibile.

Altri suggerimenti

Se ho capito bene, siete alla ricerca di uno strumento per passare attraverso il codice sorgente Perl. Ho intenzione di suggerire PPI .

Ecco un esempio acciottolato fino dalla documentazione:

#!/usr/bin/perl

use strict;
use warnings;

use PPI::Document;
use HTML::Template;

my $Module = PPI::Document->new( $INC{'HTML/Template.pm'} );

my $sub_nodes = $Module->find(
    sub { $_[1]->isa('PPI::Statement::Sub') and $_[1]->name }
);

my @sub_names = map { $_->name } @$sub_nodes;

use Data::Dumper;
print Dumper \@sub_names;

Si noti che, questa uscita volontà:

     ...
     'new',
     'new',
     'new',
     'output',
     'new',
     'new',
     'new',
     'new',
     'new',
     ...

perché più classi sono definite in HTML/Template.pm. Chiaramente, un approccio meno ingenuo avrebbe funzionato con l'albero PDom in modo gerarchico.

Un altro strumenti CPAN disponibili è Class :: ispettore

use Class::Inspector;

# Is a class installed and/or loaded
Class::Inspector->installed( 'Foo::Class' );
Class::Inspector->loaded( 'Foo::Class' );

# Filename related information
Class::Inspector->filename( 'Foo::Class' );
Class::Inspector->resolved_filename( 'Foo::Class' );

# Get subroutine related information
Class::Inspector->functions( 'Foo::Class' );
Class::Inspector->function_refs( 'Foo::Class' );
Class::Inspector->function_exists( 'Foo::Class', 'bar' );
Class::Inspector->methods( 'Foo::Class', 'full', 'public' );

# Find all loaded subclasses or something
Class::Inspector->subclasses( 'Foo::Class' );

Questo vi darà risultati simili a Class :: Sniff; si può ancora avere a che fare alcune elaborazioni sul proprio.

Ci sono risposte migliori a questa domanda, ma non sono sempre pubblicati, quindi mi sostengono la pistola più veloce del West e andare avanti e pubblicare un 'quick-fix'.

Tale strumento esiste, infatti, ed è costruito in Perl. È possibile accedere alla tabella dei simboli per qualsiasi spazio dei nomi utilizzando una variabile speciale hash. Per accedere al namespace main (quella di default):

for(keys %main::) { # alternatively %::
  print "$_\n";
}

Se il pacchetto si chiama My / Package.pm, ed è quindi in My::Package spazio dei nomi, è necessario modificare %main:: a %My::Package:: per ottenere lo stesso effetto. Vedere la perldoc perlmod ingresso su tabelle dei simboli - spiegano, e elencano alcune alternative che possono essere meglio, o almeno iniziare sulla trovare il modulo giusto per il lavoro (questo è il motto del Perl - C'è più di un modulo per farlo)

.

Se si vuole farlo senza eseguire alcun codice che si sta analizzando, è abbastanza facile da fare questo con PPI . Guarda il mio Modulo :: :: Usa estratto ; E 'un po' a corto di codice che mostra come estrarre qualsiasi tipo di elemento che si desidera da PerlDOM di PPI.

Se si vuole fare con il codice che avete già compilato, gli altri suggerimenti le risposte sono migliori.

Ho trovato un buon risposta a ciò che stavo cercando in questo di Randal Schwartz. Ha dimostrato utilizzando il modulo B :: Xref per estrarre esattamente le informazioni che cercavo. Basta sostituire la valutato one-liner ha usato con il nome del file del modulo lavorato come un campione, e apparentemente B :: Xref viene fornito con ActiveState Perl, quindi non ho bisogno di tutti i moduli aggiuntivi.

perl -MO=Xref module.pm 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top