我想扫描一个代码库,以识别目前无法访问的未定义子例程的所有实例。
举个例子:
use strict;
use warnings;
my $flag = 0;
if ( $flag ) {
undefined_sub();
}
当$flag
的计算结果为true时,会发出以下警告:
Undefined subroutine &main::undefined_sub called at - line 6
我不想依赖于在运行时发出的警告来识别未定义的子程序
strict
和warnings
pragma在这里没有帮助。 use strict 'subs'
无效。
即使以下代码段也是无声的
$ perl -Mstrict -we 'exit 0; undefined_sub()'
答案 0 :(得分:12)
来自Subroutines::ProhibitCallsToUndeclaredSubs的Perl::Critic政策可能会有所帮助
此策略检查每个非限定子例程调用在当前文件中是否具有匹配的子例程声明,或者它是否明确显示在其中一个包含模块的导入列表中。
此“政策”是Perl::Critic::StricterSubs的一部分,需要安装。那里还有一些政策。这被视为严重性4违规,因此您可以执行
perlcritic -4 script.pl
并解析neither declared nor explicitly imported
的输出,或使用
perlcritic -4 --single-policy ProhibitCallsToUndeclaredSubs script.pl
仍会标记某些合法用途,因为它要求明确导入所有子目录。
这是一个静态分析仪,我认为它应符合您的目的。
答案 1 :(得分:1)
你要求的至少在某种意义上是不可能的。请考虑以下代码段:
( rand()<0.5 ? *foo : *bar } = sub { say "Hello World!" };
foo();
有50%的可能性,这将运行正常,并有50%的可能性,它将提供&#34;未定义的子程序&#34;错误。这个决定是在运行时做出的,因此在它之前无法确定它是什么。这当然是一个用来证明一个观点的设计案例,但是在实际代码中,子例程的运行时(或编译时)生成并不常见。有关示例,请查看Moose
如何添加创建方法的函数。静态源代码分析永远无法完全分析此类代码。
B::Lint
可能与运行前的内容一样好。