一些事情:
-
Local 命名空间非常适合用于本地模块。 Perl 为此专门保留了Local。任何官方模块都不会出现在 Local 命名空间中。
- Perl 不是 Python。 Perl 会做一些不同的事情。有时有一个确切的等价物,有时没有。这没有确切等价物。接近,但不准确。
方法 #1:不要导出任何函数
如果您将完整的命名空间添加到模块中,则您在模块中定义的所有函数都可用。这是定义和使用模块中的函数的最简单方法,也是最不可能引起问题的方法。很容易看出一个函数的来源,而且两个模块使用相同的函数名也不会有问题。
我有一个名为Local::Base 的模块,其中有一个函数。我的程序可以使用此功能,只需将其称为Local::Base::foo:
我的程序
use strict;
use warnings;
use feature qw(say);
use Local::Base;
my $foo_string = Local::Base::foo("string");
say "Foo: $foo_string";
本地/Base.pm
package Local::Base;
use strict;
use warnings;
sub foo {
my $string = shift;
return qq(I've foo'd "$string"!);
}
1;
方法#2:使用Exporter Pragma 指定要自动导出的内容
Perl 有一个特殊的pragma,称为Exporter,它允许我指定哪些模块将自动导入到我的程序中。
这不像 Python,我可以指定任何已定义的函数。相反,我必须列出我想要导出的那些。这与 Python 的方式相比有一个缺点:在 Python 中,如果我编写一个新函数,它会自动导入,而无需我做任何事情。与 Python 的方式相比,它还有一个很大的优势:在 Python 中,如果我编写一个新函数,它会自动导入,而无需我做任何事情无论我是否要导入它 .你可以想象如果我写了一个我不想让人们使用的私有函数。在 Python 中,它将自动可用。在 Perl 中,除非我指定它,否则它不会是:
我的程序
use strict;
use warnings;
use feature qw(say);
use Local::Base;
my $foo_string = foo("string");
say "Foo: $foo_string";
本地/Base.pm
package Local::Base;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT = qw(foo);
sub foo {
my $string = shift;
return qq(I've foo'd "$string"!);
}
1;
现在,每当我使用Local::Base 时,foo 函数就会自动导入。
请注意,我在@EXPORT 数组中列出了我想要导出的所有函数。 (还要注意我用our 而不是my 声明该数组。our 意味着@EXPORT 是一个PACKAGE 变量。)。还要注意qw(...) 语法。这是引用词。所有单词都是数组的独立元素。你不用逗号:
my @array = ("one", "two", "three");
my @array = qw(one two three);
这两者是等价的。你也可以这样看:
my @array = qw/one two three/;
我喜欢括号,但正斜杠往往是标准。
方法#3:导出时要注意
不建议您再使用自动导出。像File::Copy 这样的旧模块仍然可以这样做,但新模块会让你导入你的东西。这也使用 Exporter pragma,但我指定 @EXPORT_OK 而不仅仅是 @EXPORT。
现在,当我指定要使用Local::Base 时,我必须指定要导入程序的函数:
我的程序
use strict;
use warnings;
use feature qw(say);
use Local::Base qw(foo);
my $foo_string = foo("string");
say "Foo: $foo_string";
本地/Base.pm
package Local::Base;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT_OK; = qw(foo);
sub foo {
my $string = shift;
return qq(I've foo'd "$string"!);
}
1;
这迫使用户记录他们想要使用的模块中的功能。这样,他们就知道导入函数的来源。它强制执行良好的编程实践。另外,如果您使用多个模块并且它们具有相似的函数名称,您可以确保使用您想要的模块中的一个。 (记住,如果你想使用另一个,你仍然可以在函数前指定包名前缀)。
如果我是一名 Python 程序员并且我不关心良好的编程实践怎么办? (等等,结果不太对……)你仍然可以(在某种程度上)通过指定 正则表达式(毕竟这是 Perl)以 Python 的方式来做:
use Local::Base '/.+/';
这将导出@EXPORT 和@EXPORT_OK 中列出的与此正则表达式匹配的所有模块。由于这匹配所有内容,它将导入您在@EXPORT 和@EXPORT_OK 中列出的所有内容。它不会导入所有功能。它只会导入@EXPORT 和@EXPORT_OK 数组中的函数。当然,您可以指定任何正则表达式,甚至是 ant 正则表达式。这将导出所有可导出的函数,但名称中带有 bar 的函数除外:
use Local::Base '!/bar/';
看看Exporter pragma,看看它还有什么其他好处。例如,您可以将函数分组到标签中。这样,用户可以只用一个标签来指定一组特定的功能。请参阅Math::Trig 了解一个很好的例子。
希望这会有所帮助。
抱歉,答案很长,但我已婚并有孩子。比如,我在除夕夜做其他事情。