Perl浅语法检查?即。不检查导入的语法

时间:2011-10-31 14:26:49

标签: perl syntax lint

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

5 个答案:

答案 0 :(得分:11)

实际上无法完成,因为导入能够影响后面代码的解析。例如use strict使得裸字不会被解析为字符串(并且更改了如何使用变量名称的规则),use constant导致定义常量subs,并use Try::Tiny更改涉及trycatchfinally的表达式解析(通过提供&原型)。更一般地说,任何将任何东西输出到调用者命名空间的模块都会影响解析,因为当名称引用现有子例程时,perl解析器会以不同方式解决歧义,而不是在不存在时解析歧义。

答案 1 :(得分:8)

这有两个问题:

  1. 如果缺少必需的模块,如何-c失败?

    有两种解决方案:

    一个。在生产中添加假/存根模块

    B中。在所有模块中,使用特殊的catch-all @INC子例程条目(使用@INC中的子元素解释here)。如果缺少库,这显然会导致模块在实际生产运行时没有失败 - 我书中的DoublePlusNotGood。

  2. 即使您可以以某种方式跳过丢失模块的失败,您仍然会在使用从缺失模块导入的标识符或从该模块的命名空间中显式使用时失败。

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

    但是,即使这样也会失败一些高级模块,它们动态地确定在自己的命名空间中创建什么以及在运行时导出什么(并且调用者代码可以动态地确定要调用哪些子节点 - heck ,有时导入哪些模块)。

    但是这种方法适用于普通的“Java / C-like”OO或程序代码,它只调用静态命名的预定义公共子,方法和访问导出的变量。

答案 2 :(得分:2)

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

答案 3 :(得分:0)

我猜你可以在你的主文件夹中为缺少的库创建存根。

答案 4 :(得分:0)

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