perl -wle 'if (0) {no_such_func()}'
以上运行没有错误,尽管是-w,因为no_such_func() 永远不会被称为。
如何让Perl检查我引用的所有函数/模块,甚至是那些 我不用?
在更现实的情况下,某些功能可能只能在特殊情况下调用 案件,但我仍然想确保它们存在。
编辑:我安装了perlcritic,但我认为我仍然做错了。我创建了这个文件:#!/bin/perl -w
use strict;
if (0) {no_such_func();}
和perlcritic说它很好(“来源OK”)。当然静态分析可以捕获no_such_func()的不存在?该程序运行良好(并没有输出)。
答案 0 :(得分:8)
你不能这样做,因为Perl直到运行时才看到函数是否存在。它不能。考虑只有eval
存在的函数:
eval 'sub foo { return $_[0]+1 }';
该行代码将在运行时创建子例程。
或者考虑Perl可以使用符号引用
my $func = 'func';
$func = "no_such_" . $func;
&$func;
在这种情况下,它正在调用您的no_such_func
函数,但您无法通过静态分析来判断。
顺便说一句,如果你想找到从未被引用的函数,至少通过静态分析,那么你可以使用像Perl :: Critic这样的工具。请参阅http://perlcritic.com/或从CPAN安装Perl :: Critic。
答案 1 :(得分:2)
嗯,这很难:当Perl解析函数调用时,它并不总是知道该函数是否存在。在声明函数之前调用函数时就是这种情况:
foo();
sub foo { say 42 }
有时,该功能只能在运行时使用:
my $bar = sub { say 42 };
my $baz = sub { say "" };
*foo = rand > 0.5 ? $bar : $baz;
foo();
(我想在此提及“只有perl可以解析Perl”模因。)
我确信在运行时无法解析函数时,你可能会破解perl内部的抱怨,但考虑到上面的用例,这不是很有用。
答案 2 :(得分:0)
如果您调用所有没有括号的潜艇,您可以强制进行编译时检查。所以以下内容将失败:
$ perl -e 'use strict; my $condvar; if ($condvar) {no_such_func}'
Bareword "no_such_func" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.
(但是,如果你写if (0)
它不会失败,似乎perl的优化器正在删除整个块而不进一步检查)
这导致您必须在使用它们之前定义所有子例程。如果你这样工作,那么有时需要“前进”声明。但是,前向声明可能永远不会得到定义,这是另一种可能的错误情况。