我是Perl的新手,目前的任务是整理和维护一个大型的、相当混乱的Perl项目。我正在使用perl-critic来帮助我检测代码中的问题(并教我最佳实践)。
现有代码中有一些地方是编码者创建了无法访问的代码。例如,他们添加了'&& 0‘作为一种懒惰的方式来注释掉一些代码分支:
if ($req->param('donut') && 0) {
unreachable code...
} else {
always branches to here...
}我曾希望perl或Critic会警告我在这种情况下无法访问的代码(条件的常量值为false),但事实并非如此。
有没有我可以使用的工具或脚本,可以可靠地检测到这种情况?
显然,我可以在源代码中搜索'&& 0‘,但除了将'&& 0’附加到if语句之外,还有许多方法可以让程序员创建无法访问的代码。
发布于 2014-04-28 16:47:55
使用B::Deparse,您可以在某些情况下检测无法访问的代码:
perl -MO=Deparse -e 'if (0 && $x) {print 1} else {print 2}'
do {
print 2
};
-e syntax OK然而,如果0不是第一个条件,这就不那么容易了:
perl -MO=Deparse -e 'if ($x && 0) {print 1} else {print 2}'
if ($x and 0) {
print 1;
}
else {
print 2;
}
-e syntax OK为什么会有所不同?好吧,如果0出现在最后,那么它之前的所有条件都必须检查。它们可能会有副作用,但这种副作用仍然会发生。此外,&&强制使用标量上下文,因此它可以更改在计算条件时调用的代码的行为。
这并不能解释为什么代码块本身没有被编译掉,对不起。我的猜测是它看起来太复杂了。
发布于 2014-04-28 18:45:52
根据choroba的回答,B::Deparse将能够向您展示代码显然无法访问的情况,以至于Perl编译器将其优化。但是,在一般情况下,它是不可能检测到的。下面的代码包含一个实际上无法访问的块。
use 5.006;
if ($] < 5) { ... }因为Perl是一个返回当前运行的$]版本的变量,use行保证该版本至少为5.006。但是,您需要一些非常聪明的技术来通过对源代码进行静态分析来解决这一问题。(顺便说一句,尽管这是一件不寻常的事情,但可以在运行时更改$]的值-请参见Acme::Futuristic::Perl -在这种情况下,代码将变得可访问。)
如果您的代码有一个很好的测试套件,那么Devel::Cover可能会很有用。您将环境变量PERL5OPT设置为-MDevel::Cover,然后运行您的测试套件(注意,它的运行速度会比平时稍微慢一点),然后运行cover命令,该命令将生成一个漂亮的HTML报告。此报告将突出显示未执行的subs、从未使用过的分支等。
https://stackoverflow.com/questions/23336115
复制相似问题