我是Perl的新手,目前我的任务是整理和维护一个庞大且相当混乱的Perl项目.我正在使用perl-critic来帮助我检测代码中的问题(并教我最佳实践).
现有代码具有编码器创建无法访问代码的位置.例如,他们添加了'&& 0'作为评论一些代码分支的懒惰方式:
if ($req->param('donut') && 0) {
unreachable code...
} else {
always branches to here...
}
Run Code Online (Sandbox Code Playgroud)
我希望perl或者Critic会在这种情况下警告我无法访问的代码(条件有一个常量值评估为false),但事实并非如此.
是否有可以使用的工具或脚本可以可靠地检测到这种事情?
显然我可以在源代码中搜索"&& 0",但除了将"&& 0"附加到if语句之外,编码器还有许多方法可以创建无法访问的代码.
使用B :: Deparse,您可以在某些情况下检测无法访问的代码:
perl -MO=Deparse -e 'if (0 && $x) {print 1} else {print 2}'
do {
print 2
};
-e syntax OK
Run Code Online (Sandbox Code Playgroud)
如果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
Run Code Online (Sandbox Code Playgroud)
它为什么不同?好吧,如果0到最后,必须检查它之前的所有条件.它们可能会产生副作用,但仍会发生.此外,&&强制标量上下文,因此它可以更改在评估条件时调用的代码的行为.
这并没有解释为什么块本身没有被编译掉,抱歉.我的猜测似乎太复杂了.
根据choroba的回答,B :: Deparse将能够向您展示代码显然无法访问的情况,Perl编译器会将其优化掉.但是,在一般情况下,无法检测到.以下代码包含一个实际上无法访问的块.
use 5.006;
if ($] < 5) { ... }
Run Code Online (Sandbox Code Playgroud)
因为$]是一个变量,它返回当前运行的Perl版本,该行保证至少为5.006 use.但是你需要一些非常聪明的技术才能弄清楚使用源代码的静态分析.(顺便说一下,虽然这是一件不寻常的事情,但可以改变$]运行时的值- 请参阅Acme :: Futuristic :: Perl - 在这种情况下代码将变得可访问.)
如果您的代码有一个不错的测试套件,Devel :: Cover可能会很有用.您将环境变量设置PERL5OPT为-MDevel::Cover,然后运行您的测试套件(注意它将比平常运行一点慢),然后运行cover将生成漂亮的HTML报告的命令.此报告将突出显示哪些子组件未执行,哪些分支从未使用过,等等.
| 归档时间: |
|
| 查看次数: |
365 次 |
| 最近记录: |