هل هناك أداة لاستخراج جميع أسماء المتغيرات والوحدة والوظائف من ملف وحدة Perl؟

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

  •  20-09-2019
  •  | 
  •  

سؤال

اعتذاري إذا كان هذا مكررًا ؛ قد لا أعرف المصطلحات المناسبة للبحث عنها.

أنا مكلف بتحليل ملف وحدة Perl (.pm) وهو جزء من تطبيق أكبر. هل هناك أداة أو تطبيق أو برنامج نصي سيذهب ببساطة عبر الكود وسحب جميع الأسماء المتغيرة وأسماء الوحدات النمطية ومكالمات الوظائف؟ والأفضل من ذلك أن يكون شيئًا من شأنه أن يحدد ما إذا كان قد تم الإعلان عنه داخل هذا الملف أو شيء خارجي.

هل توجد هذه الأداة؟ أحصل على ملف واحد فقط ، لذلك هذا ليس شيئًا يمكنني تنفيذه - فقط بعض التحليلات الثابتة الأساسية على ما أعتقد.

هل كانت مفيدة؟

المحلول

تحقق من الجديد ، ولكن الموصى به جيدًا Class::Sniff.

من المستندات:

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

هذا سوف يحصل عليك معظم الطريق هناك. بعض variables, اعتمادًا على النطاق ، قد لا يكون متاحًا.

نصائح أخرى

إذا فهمت بشكل صحيح ، فأنت تبحث عن أداة للذهاب عبر رمز مصدر Perl. سأقترح PPI.

فيما يلي مثال مرصوف بالحصى من المستندات:

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

لاحظ أن هذا سوف يخرج:

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

لأنه يتم تعريف فئات متعددة في HTML/Template.pm. من الواضح أن النهج الأقل ساذجة من شأنه أن يعمل مع شجرة بدوم بطريقة هرمية.

أدوات CPAN أخرى متوفرة الفصل :: المفتش

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

هذا سوف يمنحك نتائج مماثلة للفئة :: شم ؛ قد لا يزال يتعين عليك القيام ببعض المعالجة بمفردك.

هناك إجابات أفضل على هذا السؤال ، لكنهم لا يتم نشرهم ، لذلك سأطالب أسرع بندقية في الغرب وأمضي قدماً ونشر "الإصلاح السريع".

مثل هذه الأداة موجودة ، في الواقع ، وهي مدمجة في بيرل. يمكنك الوصول إلى جدول الرموز لأي مساحة اسم باستخدام متغير تجزئة خاص. للوصول إلى main مساحة الاسم (الافتراضي واحد):

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

إذا تم تسمية الحزمة الخاصة بك/package.pm ، وبالتالي في مساحة الاسم My::Package, ، سوف تتغير %main:: إلى %My::Package:: لتحقيق نفس التأثير. انظر Perldoc perlmod الدخول على جداول الرموز - يشرحون ذلك ، ويسردون بعض البدائل التي قد تكون أفضل ، أو على الأقل تبدأ في العثور على الوحدة النمطية المناسبة للوظيفة (هذا هو شعار Perl - هناك أكثر من وحدة واحدة للقيام بذلك).

إذا كنت ترغب في القيام بذلك دون تنفيذ أي رمز تقوم بتحليله ، فمن السهل إلى حد ما القيام بذلك PPI. تحقق من بلدي الوحدة النمطية :: الاستخدام :: استخراج; ؛ إنه جزء قصير من التعليمات البرمجية يوضح لك كيفية استخراج أي نوع من العناصر التي تريدها من PPI's Perldom.

إذا كنت ترغب في القيام بذلك باستخدام التعليمات البرمجية التي قمت بتجميعها بالفعل ، فإن الاقتراحات الأخرى في الإجابات أفضل.

لقد وجدت إجابة جيدة على ما كنت أبحث عنه في هذا عمودي بقلم راندال شوارتز. لقد أظهر باستخدام وحدة B :: XREF لاستخراج المعلومات التي كنت أبحث عنها بالضبط. ما عليك سوى استبدال المُقيّم الذي تم تقييمه في اسم ملف الوحدة النمطية مثل البطل ، ويبدو أن B :: Xref يأتي مع Activestate Perl ، لذلك لم أكن بحاجة إلى أي وحدات إضافية.

perl -MO=Xref module.pm 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top