说我有一个Perl模块:
use Foo::Bar;
sub add {
return Foo::Bar::func() + Foo::Buzz::func();
}
此模块中存在错误,因为它会忘记use Foo::Buzz
。我的单元测试并不总能捕获此错误,例如,如果Foo::Buzz
的测试运行较早且导入Foo::Buzz
之前导入add()
。如果我在生产代码中使用此模块,它将失败并显示错误Foo::Buzz
未导入。
如何检查代码中使用的所有模块是否也已导入?
编辑:我想在将代码部署到生产环境之前检查代码,以避免发生任何错误。该示例将在生产中失败,我想在此之前捕获错误,例如,当我运行单元测试时。我想要一个工具或一些代码,我可以在部署之前运行它来捕获这个错误,比如flake8 for python。
答案 0 :(得分:2)
简短的回答是你无法。由于Perl是一种动态语言,因此您无法检查是否在运行时加载所有模块,因为您无法检查代码中是否存在其他错误。
您仍然可以使用某些静态代码分析,尝试在未显示This::Pattern
的文件中查找use This::Pattern;
,但它并不保证任何内容。
答案 1 :(得分:0)
如果Perl严格来说是动态语言,您可以轻松检查程序中是否安装了模块。问题是Perl不是100%动态的。它进行了一些编译,部分编译工作在检查模块后完成。
Bulrush走在正确的轨道上。不幸的是,您可以使用use
子句来执行此操作。预编译会检查use
,因此您在执行eval
之前会收到错误。
然而,use perldoc页面中有一条线索:
你去吧!您可以在BEGIN子句中使用
- 使用模块列表
- 使用模块
- 使用版本
从命名模块将一些语义导入当前包,通常通过将某些子例程或变量名称别名到包中。 完全等同于 到
的BEGIN { require Module; Module->import( LIST ); }
强>
require
,该子句甚至在解析文件的其余部分之前执行。您可以在那里使用eval
来查看这是否有效。您需要使用包变量作为标志,以查看是否因为范围问题而起作用。离开BEGIN
子句时,常规的词法范围变量将消失。
BEGIN {
our $FOO_BAR_available = 0; # Must be a package variable
eval {
require Foo::Bar;
Module->import( qw(...) ); # No need if you don't import any subroutines
};
if (not $@ ) {
$FOO_BAR_AVAILABLE = 0;
}
}
然后在你的计划中,你有:
our $FOO_BAR_available;
if ( not $FOO_BAR_available ) {
# Here be dragons...
}
else {
# Back to your normal code...
}
our $FOO_BAR_available
有点令人困惑。您没有再次声明此变量,您只是说明您要使用此变量而不使用完整的包名称作为前缀。该变量在BEGIN
子句中设置,这不会影响该值。
如果此模块是正确编写,则可以完全跳过包变量的使用。模块假设设置一个名为$VERSION
的包变量。您可以将此变量用作标志:
BEGIN {
eval {
require Foo::Bar;
Module->import( qw(...) ); # No need if you don't import any subroutines
};
}
注意我不仅不必声明包变量,我甚至不必验证eval
语句是否有效。
然后在你的程序中......
if ( not $FOO::BAR::VERSION ) {
# Here be dragons...
}
else {
# Back to your normal code...
}
如果模块设置了$VERSION
变量,则表示已加载。否则,您知道模块未加载。
我希望在将代码部署到生产环境之前检查代码,以避免发生任何错误。该示例将在生产中失败,我想在此之前捕获错误,例如,当我运行单元测试时。
这是我的建议。它不像运行脚本那么简单,但它要好得多:
Foo::Bar
很好,但我不应该使用Far::Bu
,因为生产没有这个。这是第一步。我对那些不知道生产环境是什么的地方感到惊讶。使用Jenkins。 Jenkins是一个持续构建的引擎。是的,你不能编译Perl,但你仍然可以从Jenkins中受益:
您不能在生产环境中正常运行flake8
。到那时,它已经晚了一点。
Perl有很多很好的工具可以执行类似的功能:
lint
程序一样,可以捕获编码问题。但是,在您准备好在Production中运行之前,这是要做的事情。使用Vagrant帮助开发人员设置自己的私有生产环境进行测试。使用Jenkins确保您在类似生产的环境中进行测试,并在发生错误时立即捕获错误,而不是在UAT测试之后。