- 导出子程序 foo,导入具有该子程序的模块。最后在你的 perl 脚本中调用它。
为了做到这一点,您将在实现 sub的 module/中使用Exporter 。package
你告诉你的模块它将通过@EXPORT_OK
and导出什么@EXPORT
。如果您use
是模块,则在编译时会将内容导入您当前的命名空间。以下 to 语句是等价的。
# This is the same...
use Module;
# ... as this
BEGIN {
require Module;
Module->import();
}
如果您有要在主脚本中使用的东西,或者您要经常使用,您想这样做。一些示例是List::Util、Data::Dumper或use feature 'say'
. 当然你也可以在其他模块中使用它。
use Data::Dumper;
use List::Util qw(max);
use feature qw(say);
my @foo = (1, 2, 3, 4, 5, 23);
print Dumper \@foo;
say max(@foo);
问题是在这里,你“污染”了你的命名空间。如果必须,请执行此操作,但请记住它发生在编译时,因此它不是有条件的。你不能说:
if ($foo) {
use Some::Module 'foo';
foo($foo);
} else {
use Something::Else 'bar';
bar();
}
它将在编译时同时加载Some::Module
, Something::Else
从而增加程序消耗的时间和内存。该条件当然会起作用,但效率不高。
- 在您的 perl 脚本中创建该模块的对象,最后使用该对象调用 foo。
这是面向对象的方法。它(如上所述)无法与其他方法相提并论。您不需要导入对象的方法。use
您只需使用或(见上文)加载您的类(这是一个模块)require
,创建一个实例并根据自己的喜好使用它的方法。但是,您需要一个面向对象的模块。如果您对它的工作原理感兴趣,请先查看perlootut。
- 使用路径直接调用 foo,例如 myDir::Module::foo();。
它实际上并不完全是它的路径,而是它的名称(空间)。例如,Data::DumperDumper.pm
位于文件夹Data
中,在您的目录中的某个位置lib
。但这并不重要。
第一种方法的主要区别在于您省略了导入部分。如果您想构建有条件地加载某些模块的东西,或者如果您在一个巨大的(可能是遗留的)应用程序中并且不想污染命名空间,这很有用。
if ($order_has_some_condition) {
require Very::Long::NameSpace::For::This::Condition::Module;
Very::Long::NameSpace::For::This::Condition::Module::do_stuff_with_an_order($order);
}
想象一下,这段代码在一个有 2k 行的遗留子代码中,并且发生了很多事情,其中大部分在我们的例子中从未被调用过。我们不希望use
我们的模块,使其可用于在这段巨大的代码中处理的大约 100 种不同情况中的每一种。相反,我们只想在真正需要时才加载它。现在我们require
使用全名直接调用模块并调用它的子。
总之,第一种方式和第三种方式各有千秋。它们都需要存在,如果合适的话,它们都应该被使用。在某些情况下,它只是味道,但在其他情况下,决定是有意义的。第二种,OOp,方法完全是另外一回事。
没有真正的速度差异,正如 Borodin 所说,Perl 很快。当然,如果您不import
填充,则不必为导入“付费”。在 10 行脚本中,这无关紧要。在一个巨大文件中可能包含数千行代码和许多用例的遗留软件中,这非常重要。
我希望这可以帮助您做出决定。