我们正在考虑Perl项目中的公共代码。一个主程序应该分成几个可重用的模块。
我们的程序名是validate_results.pl
,其中包含一组验证命令。我们计划将其拆分为小模块,以便validate_results.pl
应该像:
use Common::Validate_Results;
use Common::Validate_Results::CommonCommands;
use Common::Validate_Results::ReturnCodeValidation;
...
根据我的理解,我应该创建一个Common文件夹,并且{@ 1}}应该存在。再次在Validate_Results.pm
下,应创建Common
文件夹,并且应该存在Validate_Results
和CommonCommands
个文件夹。
是否必须存在所有这些文件夹,或者我们是否可以将所有Perl程序放在一个文件夹中并对其进行逻辑分组,并仍使用上述方式访问模块(比如使用ReturnCodeValidation
)
答案 0 :(得分:6)
文件系统层次结构是必需的。 A :: B :: C将始终位于A / B / C.pm,位于@INC。
如果你有来解决这个问题,请阅读perldoc -f require,特别是在@INC中寻找有关子程序引用的部分。是的,你可以让模块加载器做一些奇怪的事情,如果这是你真正想要的;但那不是你想要的,相信我。坚持惯例,就像其他99.9999999%的Perl应用程序一样。
答案 1 :(得分:3)
如果您想“使用”您的模块,那么您必须符合结构。如果你想绕过它,你可以“需要”你的模块,将文件名传递给require。
但是,你真的不应该这样做。如果您真的不想拥有目录结构,请将其从模块名称中取出(如果您的模块名称与CPAN中更通用的模块名称冲突,则可能导致将来出现问题)。只需通过Find :: Bin将脚本目录添加到INC路径并直接使用模块:use FindBin;
use lib $FindBin::Bin;
use ValidateResults;
use CommonCommands;
use ReturnCodeValidation;
HTH
答案 2 :(得分:2)
以下是模块及其子模块在同一文件中的示例:
package Foo;
use strict;
use Exporter 'import';
our @EXPORT = ( 'from_foo' );
sub from_foo { print "from_foo\n"; }
package Foo::Bar;
use strict;
use Exporter 'import';
our @EXPORT = ( 'from_foo_bar' );
sub from_foo_bar { print "from_foo_bar\n"; }
1;
在你的程序中,如果你使用模块 Foo (带有.pm文件的模块):
use Foo;
除了作为规范名称(Foo :: Bar :: from_foo_bar)之外,您将可以访问 Foo :: Bar 函数。您可以像这样导入它们:
use Foo;
Foo::Bar->import;
请注意,您无法执行此操作:
use Foo::Bar;
因为没有文件 Foo / Bar.pm 。
答案 3 :(得分:0)
'use'命令中的包名实际上只是一个以.pm文件结尾的路径,因此您不需要具有每个包名称的文件夹。在您的示例中,您需要文件夹:
Common
Common/Validate_Results
但你不需要文件夹:
Common/Validate_Results/CommonCommands
Common/Validate_Results/ReturnCodeValidation
.pm文件中的实际包名称不必与加载它的'use'命令中的名称相同。但保持路径与包名称一致总是一个好主意。