2013-10-26 3 views
1
perl -wle 'if (0) {no_such_func()}' 

Вышеприведенные работает без ошибок, несмотря на -w, потому что no_such_func() никогда не вызывается.Сделать Perl предупредить меня о несуществующих неиспользуемых функций

Как сделать Perl проверять все функции/модули, которые я ссылаюсь, даже на номера Я не использую?

В более реалистичном случае некоторые функции могут быть вызваны только в специальных случаях , но я все равно хочу убедиться, что они существуют.

EDIT: Я установил perlcritic, но я думаю, что я все еще делаю что-то неправильно. Я создал этот файл:

#!/bin/perl -w 
use strict; 
if (0) {no_such_func();} 

и perlcritic сказал, что все в порядке («источник ОК»). Разумеется, статический анализ может уловить отсутствие no_such_func()? Программа также отлично работает (и не производит выход).

+2

http://stackoverflow.com/questions/8499608/how-do-i-get-perl-c-to-throw-undefined-or-undeclared-function-errors могут быть полезны – stevemarvell

ответ

8

Вы не можете этого сделать, потому что Perl не видит, существуют ли функции до выполнения. Это невозможно. Рассмотрим функцию, которая только получает eval-е изд в существование:

eval 'sub foo { return $_[0]+1 }'; 

Эта строка кода будет создать подпрограмму во время выполнения.

Или считают, что Perl может использовать символические ссылки

my $func = 'func'; 
$func = "no_such_" . $func; 
&$func; 

В этом случае он звонит no_such_func функцию, но вы не можете сказать, с помощью статического анализа.

BTW, если вы хотите найти функции, которые никогда не ссылаются, по крайней мере, через статический анализ, вы можете использовать инструмент Perl :: Critic. См. http://perlcritic.com/ или установите Perl :: Critic из CPAN.

+0

Я думаю, что хочу пойти Другой способ: найти все функции, которые статически ссылаются, но никогда не определяются. – barrycarter

+1

OK, установка Perl :: Критик :: StricterSubs сделал трюк, спасибо всем! – barrycarter

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 «meme» на данный момент.)

Я уверен, что вы могли бы взломать внутренние элементы perl, чтобы жаловаться, когда функция не может быть решена до запуска, но это не очень полезно с учетом вариантов использования выше.

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 удаляет весь блок без проверки дальше)

Это приводит к тому, что вам должны определить все подпрограммы перед их использованием. Если вы работаете так, то иногда необходимы «форвардные» декларации.Но тогда возможно, что передняя декларация никогда не получит определения, что является еще одним возможным случаем ошибки.