Perl 浅语法检查? IE。不检查导入的语法
如何对 perl 文件执行“浅层”语法检查。标准 perl -c
很有用,但它会检查导入的语法。有时这很好,但当您在代码存储库中工作并推送到运行环境并且您在存储库中定义了一个函数但尚未推送到运行环境时,这并不好。它无法检查函数,因为导入引用系统路径(即使用 Custom::Project::Lib qw(foo bar baz))。
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)).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
实际上这是不可能完成的,因为导入能够影响后续代码的解析。例如,
use strict
使得裸字不会被解析为字符串(并更改如何使用变量名的规则),use Constant
导致常量 subs 被解析为字符串。定义,并且use Try::Tiny
更改涉及try
、catch
或finally
的表达式的解析(通过给他们&
原型)。更一般地说,任何将任何内容导出到调用者名称空间的模块都可能影响解析,因为当名称引用现有子例程时,perl 解析器会以不同的方式解决歧义。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, anduse Try::Tiny
changes the parse of expressions involvingtry
,catch
, orfinally
(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.这有两个问题:
如果缺少所需的模块,
-c
如何不失败?有两种解决方案:
A.在生产中添加一个 fake/stub 模块
B.在所有模块中,使用特殊的包罗万象的 @INC 子例程条目(在
@INC
中使用 subs 已解释此处)。这显然存在一个问题,即如果缺少库,模块在实际生产运行时不会失败 - 我书中的 DoublePlusNotGood。即使您可以以某种方式跳过丢失模块的失败,但使用从丢失模块导入的标识符或从该模块的命名空间显式使用的标识符仍然会失败。
对此唯一现实的解决方案是回到 #1a 并使用假存根模块,但这一次为每个公共接口都声明并(根据需要)导出标识符。例如,不执行任何操作的子变量或虚拟变量。
但是,对于某些高级模块来说,即使这样也会失败,这些模块动态确定在自己的命名空间中创建什么以及在运行时导出什么(并且调用者代码可以动态确定要调用哪些子模块 - 哎呀,有时要导入哪些模块)。
但这种方法对于普通的“类 Java/C”OO 或仅调用静态命名的预定义公共子、方法和访问导出变量的过程代码来说效果很好。
There are two problems with this:
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.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.
我建议最好将代码存储库包含在语法检查中。
perl -I/path/to/working/code/repo/local_perl/ -c
或先设置PERL5LIB=/path/to/working/code/repo/local_perl/
运行perl -c
。任何一个选项都应该允许您检查工作代码,假设您的工作代码位于与实时代码类似的目录结构中。I would suggest that it's better to include your code repository in your syntax check.
perl -I/path/to/working/code/repo/local_perl/ -c
or setPERL5LIB=/path/to/working/code/repo/local_perl/
prior to runningperl -c
. Either option should allow you to check against your working code, assuming you have it in a directory structure similar to your live code.我想你可以为你的主文件夹中缺少的库制作存根。
I guess you could make stubs for the missing libraries in your home folder.
你研究过PPI吗?我认为它确实遵循导入,但是也许可以更容易地对其进行修改以猜测函数名称的样子。
Have you looked into PPI? I think it does follow imports, however it could perhaps be more easily modified to guess what looks like a function name.