8

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

4

5 回答 5

11

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

于 2011-10-31T14:36:20.230 回答
8

这有两个问题:

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

    有两种解决方案:

    A. 在生产中添加一个 fake/stub 模块

    B. 在所有模块中,使用一个特殊的包罗万象的@INC 子例程条目(在此处@INC解释使用 subs in )。如果缺少库,这显然存在模块在实际生产运行时不会失败的问题 - 我书中的 DoublePlusNotGood。

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

    唯一现实的解决方案是回到 #1a 并使用假存根模块,但这一次,每个公共接口都有一个已声明和(根据需要)导出的标识符。例如,什么都不做的子或虚拟变量。

    但是,即使对于一些动态确定在自己的命名空间中创建什么以及在运行时导出什么的高级模块来说,即使这样也会失败(并且调用者代码可以动态确定要调用哪些子程序——哎呀,有时要导入哪些模块)。

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

于 2011-10-31T14:37:40.387 回答
2

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

于 2011-10-31T15:53:46.053 回答
0

我想您可以为您的主文件夹中缺少的库制作存根。

于 2011-10-31T14:29:26.817 回答
0

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

于 2014-05-08T13:19:12.033 回答