Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl shallow syntax check? ie. do not check syntax of imports

Tags:

syntax

lint

perl

How can I perform a "shallow" syntax check on perl files. The standard perl -c is useful but it checks the syntax of imports. This is sometimes nice but not great when you work in a code repository and push to a running environment and you have a function defined in the repository but not yet pushed to the running environment. It fails checking a function because the imports reference system paths (ie. use Custom::Project::Lib qw(foo bar baz)).

like image 555
Dale Forester Avatar asked Oct 31 '11 14:10

Dale Forester


2 Answers

It can't practically be done, because imports have the ability to influence the parsing of the code that follows. For example use strict makes it so that barewords aren't parsed as strings (and changes the rules for how variable names can be used), use constant causes constant subs to be defined, and use Try::Tiny changes the parse of expressions involving try, catch, or finally (by giving them & prototypes). More generally, any module that exports anything into the caller's namespace can influence parsing because the perl parser resolves ambiguity in different ways when a name refers to an existing subroutine than when it doesn't.

like image 51
hobbs Avatar answered Oct 06 '22 11:10

hobbs


There are two problems with this:

  1. How to not fail -c if the required modules are missing?

    There are two solutions:

    A. Add a fake/stub module in production

    B. In all your modules, use a special catch-all @INC subroutine entry (using subs in @INC is explained here). This obviously has a problem of having the module NOT fail in real production runtime if the libraries are missing - DoublePlusNotGood in my book.

  2. Even if you could somehow skip failing on missing modules, you would STILL fail on any use of the identifiers imported from the missing module or used explicitly from that module's namespace.

    The only realistic solution to this is to go back to #1a and use a fake stub module, but this time one that has a declared and (as needed) exported identifier for every public interface. E.g. do-nothing subs or dummy variables.

    However, even that will fail for some advanced modules that dynamically determine what to create in their own namespace and what to export in runtime (and the caller code could dynamically determine which subs to call - heck, sometimes which modules to import).

    But this approach would work just fine for normal "Java/C-like" OO or procedural code that only calls statically named predefined public subs, methods and accesses exported variables.

like image 35
DVK Avatar answered Oct 06 '22 11:10

DVK