Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get perl -c to throw Undefined or Undeclared function errors?

Tags:

perl

Coming from a C++ background, I religiously use the use strict and use warnings features of Perl:

#!/usr/bin/perl -w
use strict;
use warnings;

$foo = 1; #Throws "$foo" requires explicit package name error

foobar( 1 );  

The use strict construct is immensely helpful to catch errors when you mistype a variable name. Is there an equivalent construct to catch mistyped function names? In the above example, it would be great if there was something like perl -c that caught the fact that there is no foobar function available to call. Of course running the script throws an Undefined subroutine error, but I would like to catch it sooner.

like image 586
parapura rajkumar Avatar asked Dec 14 '11 04:12

parapura rajkumar


4 Answers

Try this:

perl -MO=Lint -cw /path/to/script.pl

This uses the B::Lint module.

like image 172
sjs Avatar answered Oct 19 '22 21:10

sjs


The module Sub::StrictDecl does what you are looking for, and with lexical scope.

This module provides optional checking of subroutine existence at compile time. This checking detects mistyped subroutine names and subroutines that the programmer forgot to import. Traditionally Perl does not detect these errors until runtime, so it is easy for errors to lurk in rarely-executed or untested code.

Specifically, where checking is enabled, any reference to a specific (compile-time-constant) package-based subroutine name is examined. If the named subroutine has never been declared then an error is signalled at compile time. This does not require that the subroutine be fully defined: a forward declaration such as "sub foo;" suffices to suppress the error. Imported subroutines qualify as declared. References that are checked include not only subroutine calls but also pure referencing such as "\&foo".

This checking is controlled by a lexically-scoped pragma. It is therefore applied only to code that explicitly wants the checking, and it is possible to locally disable checking if necessary. Checking might need to be turned off for code that makes special arrangements to put a subroutine in place at runtime, for example.

like image 20
Eric Strom Avatar answered Oct 19 '22 20:10

Eric Strom


Seeing ikegami's Answer reminded me that perlcritic can identify undeclared subs, but you need to install the Perl::Critic::StricterSubs policy, which is not part of the core Perl::Critic distribution.

perlcritic -4 mycode.pl

Subroutine "foobar" is neither declared nor explicitly imported at line 10, column 1. This might be a major bug. (Severity: 4)

like image 6
toolic Avatar answered Oct 19 '22 22:10

toolic


Perl cannot possibly know at compile time that there won't be a sub to call once the sub call is reached, so -c cannot possibly tell you that.

perlcritic is a tool designed to scan Perl code and guess at possible problems like this one. The Perl::Critic::StricterSubs perlcritic rule checks for this problem.

like image 2
ikegami Avatar answered Oct 19 '22 22:10

ikegami