2011-10-31 103 views
8

如何对perl文件执行“浅”语法检查。标准perl -c很有用,但它检查导入的语法。当你在一个代码仓库中工作并推送到一个正在运行的环境,并且你有一个在仓库中定义的函数但尚未推送到正在运行的环境时,这有时是很好但不是很好。它检查函数失败,因为导入引用系统路径(即使用Custom :: Project :: Lib qw(foo bar baz))。Perl浅层语法检查?即。不检查导入语法

回答

11

它实际上无法完成,因为导入有能力影响后面代码的解析。例如use strict使得它使得裸字不被解析为字符串(和改变规则的名称如何变量可以使用),use constant导致要定义的常数潜艇,和use Try::Tiny改变表达式涉及trycatch,或finally解析(通过给他们&原型)。更一般地说,任何将任何内容导出到调用者名称空间的模块都可能影响解析,因为当名称引用现有子例程时,perl解析器以不同方式解决歧义。

0

我想你可以在你的home文件夹中为缺少的库做存根。

8

有两个问题:

  1. 如果所需的模块缺少如何不会失败-c

    解决办法有两个:

    A.添加一个假的/存根模块生产

    B.在所有的模块,使用特殊的包罗万象的@INC子程序入口(使用潜艇在@INC是解释为here)。这显然有一个问题,就是在实际的生产运行时,如果库缺失 - 模块没有在我的书中出现DoublePlusNotGood失败。

  2. 即使您可以以某种方式跳过对失踪模块的失败,您仍然无法使用从缺失模块导入的标识符或从该模块的名称空间显式使用的标识符。

    对此的唯一现实的解决方案是回到#1a并使用虚假的存根模块,但这次为每个公共接口声明和(根据需要)导出的标识符。例如。无所作为的潜艇或虚拟变量。

    然而,即使这样,也不能对一些先进的模块动态确定如何在自己的命名空间创建和如何在运行时输出(和呼叫者代码可以动态地确定要调用哪个潜艇 - 赫克,有时哪些模块导入)。

    但是,这种方法对于只能调用静态命名的预定义公共子类,方法和访问导出变量的普通“Java/C-like”OO或过程代码来说工作得很好。

+0

感谢您的深入讨论,我非常感谢 –

2

我会建议最好在你的语法检查中包含你的代码库。 perl -I/path/to/working/code/repo/local_perl/ -c或设置PERL5LIB=/path/to/working/code/repo/local_perl/,然后运行perl -c。任一选项都应允许您检查您的工作代码,假设您的目录结构与您的实时代码类似。

0

你看过PPI了吗?我认为它确实遵循导入,但它可能更容易被修改以猜测看起来像一个函数名称。