是否有从一个Perl模块文件中提取出所有的变量,模块和函数名的工具吗?
-
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
定义。显然,少天真的做法将与PDOM树工作在一个分层的方式。
另一个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' );
这会给你类似的结果类::嗅;你可能还要做一些自己的处理。
有这个问题更好的答案,但他们没有得到公布,所以我会要求最快的枪在西部和继续前进,张贴“速战速决”。
这样的工具存在,实际上,并内置到的Perl。您可以通过使用一个特殊的散列变量访问的符号表的任何命名空间。要访问main
命名空间(默认的):
for(keys %main::) { # alternatively %::
print "$_\n";
}
如果你的包被命名为My / Package.pm,并因此在命名空间My::Package
,你会改变%main::
到%My::Package::
来达到同样的效果。见的perldoc perlmod的作品的符号表 - 他们解释,他们列出这可能会更好,或者至少得到一些替代你开始寻找合适的模块的工作(这是Perl的座右铭 - 有多于一个的模块做)
如果你想这样做不执行,你正在分析的任何代码,这是相当容易的 PPI 。看看我的模块::使用::提取;它是简短的代码位向您介绍如何提取您从PPI的PerlDOM想要的任何类型的元素。
如果你想用代码,您已经编译做到这一点,在回答另一个建议是更好的。
我找到了一个不错的答案,我一直在寻找这个列一>通过兰德尔施瓦茨。他展示了使用B ::外部参照模块来准确提取我一直在寻找的信息。只需更换他与模块的文件名使用的评估一个班轮工作就像一个冠军,显然B ::外部参照自带的ActiveState Perl的,所以我并不需要任何额外的模块。
perl -MO=Xref module.pm