Question

perl -wle 'if (0) {no_such_func()}'

The above runs without errors, despite the -w, because no_such_func() is never called.

How do I make Perl check all functions/modules I reference, even ones I don't use?

In a more realistic case, some functions may only be called in special cases, but I'd still like to make sure they exist.

EDIT: I installed perlcritic, but I think I'm still doing something wrong. I created this file:

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

and perlcritic said it was fine ("source OK"). Surely static analysis could catch the non-existence of no_such_func()? The program also runs fine (and produces no output).

Was it helpful?

Solution

You can't do it because Perl doesn't see if functions exist until runtime. It can't. Consider a function that only gets evaled into existence:

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

That line of code will create a subroutine at runtime.

Or consider that Perl can use symbolic references

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

In that case, it's calling your no_such_func function, but you can't tell via static analysis.

BTW, if you want to find functions that are never referenced, at least via static analysis, then you can use a tool like Perl::Critic. See http://perlcritic.com/ or install Perl::Critic from CPAN.

OTHER TIPS

Hmm, this is difficult: When Perl parses a function call, it doesn't always know whether that function will exist. This is the case when a function is called before it's declared:

foo();
sub foo { say 42 }

Sometimes, the function may only be made available during runtime:

my $bar = sub { say 42 };
my $baz = sub { say "" };
*foo = rand > 0.5 ? $bar : $baz;
foo();

(I'd like to mention the “Only perl can parse Perl” meme at this point.)

I'm sure you could hack the perl internals to complain when the function can't be resolved before run time, but this is not really useful considering the use cases above.

You can force compile-time checks if you call all subs without parentheses. So the following will fail:

$ 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.

(However, it does not fail if you write if (0), it seems that perl's optimizer is removing the whole block without checking any further)

This has the consequence that you have to define all subroutines before using them. If you work like this, then sometimes "forward" declarations are necessary. But then it's possible that a forward declaration never gets a definition, which is another possible error case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top