Gibt es ein Tool zum Extrahieren aller Variablen-, Modul- und Funktionsnamen aus einer Perl -Moduldatei?

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

  •  20-09-2019
  •  | 
  •  

Frage

Ich entschuldige mich, wenn dies ein Duplikat ist; Ich kenne möglicherweise nicht die richtigen Begriffe, nach denen ich suchen kann.

Ich habe die Aufgabe, eine Perl -Moduldatei (.pm) zu analysieren, die ein Fragment einer größeren Anwendung ist. Gibt es ein Tool, eine App oder ein Skript, das einfach den Code durchläuft und alle Variablennamen, Modulnamen und Funktionsaufrufe herauszieht? Noch besser wäre etwas, das identifizieren würde, ob es in dieser Datei deklariert wurde oder etwas Externes ist.

Gibt es ein solches Tool? Ich bekomme nur die eine Datei, also kann ich das nicht ausführen - nur eine grundlegende statische Analyse, denke ich.

War es hilfreich?

Lösung

Schauen Sie sich das neue, aber gut empfohlene an Class::Sniff.

Aus den Dokumenten:

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";
}

Dies bringt Sie den größten Teil des Weges dorthin. Etwas variables, Abhängig vom Umfang ist möglicherweise nicht verfügbar.

Andere Tipps

Wenn ich richtig verstehe, suchen Sie nach einem Tool, um den Perl -Quellcode zu durchlaufen. Ich werde vorschlagen PPI.

Hier ist ein Beispiel, das aus den Dokumenten gestoßen ist:

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

Beachten Sie, dass dies ausgegeben wird:

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

Weil mehrere Klassen in definiert sind in HTML/Template.pm. Ein weniger naiver Ansatz würde eindeutig auf hierarchische Weise mit dem Pdom -Baum funktionieren.

Ein weiterer verfügbarer CPAN -Tools ist Klasse :: Inspektor

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' );

Dies gibt Ihnen ähnliche Ergebnisse wie Klasse :: Sniff; Möglicherweise müssen Sie noch eine gewisse Verarbeitung selbst durchführen.

Es gibt bessere Antworten auf diese Frage, aber sie werden nicht veröffentlicht, also werde ich die schnellste Waffe im Westen beanspruchen und eine "Schnellfix" posten.

Ein solches Werkzeug existiert tatsächlich und ist in Perl eingebaut. Sie können auf die Symboltabelle für einen beliebigen Namespace zugreifen, indem Sie eine spezielle Hash -Variable verwenden. Zugreifen auf die main Namespace (der Standard):

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

Wenn Ihr Paket mein/package.pm heißt und sich daher im Namespace befindet My::Package, Sie würden sich ändern %main:: zu %My::Package:: den gleichen Effekt erzielen. Siehe das PERLDOC Perlmod Eintritt in Symboltabellen - sie erklären es und listen ein paar Alternativen auf, die möglicherweise besser sind, oder bringen Sie zumindest dazu, das richtige Modul für den Job zu finden (das ist das Perl -Motto - es gibt mehr als ein Modul, um dies zu tun).

Wenn Sie es tun möchten, ohne einen Code auszuführen, den Sie analysieren, ist es ziemlich einfach, dies zu tun PPI. Sieh dir mein an Modul :: Verwendung :: Extrakte; Es ist ein kurzes Stück Code zeigt Ihnen, wie Sie jede Art von Element extrahieren, die Sie von PPIs Perldom gewünscht haben.

Wenn Sie dies mit Code tun möchten, den Sie bereits zusammengestellt haben, sind die anderen Vorschläge in den Antworten besser.

Ich fand eine ziemlich gute Antwort auf das, wonach ich darin gesucht habe Säule Von Randal Schwartz. Er demonstrierte mit dem B :: Xref -Modul, um genau die Informationen zu extrahieren, nach denen ich gesucht habe. Der ersetzte Ersetzen des bewerteten Ein-Liners, den er mit dem Dateinamen des Moduls verwendete, funktionierte wie ein Champion, und anscheinend verfügt B :: Xref mit Aktivität Perl, sodass ich keine zusätzlichen Module benötigte.

perl -MO=Xref module.pm 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top