模块: ./FOO/BAR/Foobar.pm
use strict;
use warnings;
package Foobar;
our($VERSION , @ISA , @EXPORT , @EXPORT_OK , %EXPORT_TAGS , $FOO);
BEGIN {
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(&foo);
}
sub foo {
print "Loaded\n";
$FOO = q{some val};
}
1;
计划: ./Caller.pl
#!/usr/bin/perl
use strict;
use warnings;
use FOO::BAR::Foobar qw/foo/;
Foobar::foo(); # works
foo(); # errors out - can't find &main::foo
我列出了我尝试过的所有东西,但是有很多东西 - 正如你所看到的,我有更多的全球Foobar全局值而不是列出的全局值。我删除了BEGIN,并按照PerlMonks上[较旧]帖子的建议完成了其他一些事情。
我想我曾经读过一次,如果包名与模块名相同,则Exporter默认以某种方式工作。我不知道将模块放在子目录中是否可以改变该行为(?)。但是,我很想知道我是如何搞砸的。
答案 0 :(得分:5)
如果模块位于FOO / BAR / Foobar.pm,则包名称应为FOO::BAR::Foobar
。
我还会从@EXPORT_OK数组中删除&
符号。
答案 1 :(得分:4)
除了choroba的回答,我在post找到了这个Sherm Pendley,我认为这是我多年前读过的那篇文章:
在导出函数的非OO模块中,它们必须相同 出口商要做的事情。使用()模块时 - 让我们称之为“Foo”, 以下步骤基本上是发生的事情:
BEGIN { require Foo; import Foo qw(args); }
第二步是可选的 - 如果模块中没有import()函数 Foo,use()仍然会成功。
现在,让我们假设包Bar在Foo.pm中。 Foo.pm由编译 require()没有问题。因为它的代码在包Bar中,所以 从Exporter显式声明或继承的import()函数是 也被编译到那个包中。
但是use()仍尝试在包中调用import()函数 富。更糟糕的是,因为import()是可选的,它将静默失败。该 只有线索,用户会得到一个出错的地方,就是没有 包Bar中声明的函数可以在没有完全使用的情况下使用 指定的包名,即Bar :: baz(),因为import()失败了 在当前包中为它们创建别名。
其他事情也可能取决于filename = package约定。采取 例如,perldoc。如果您的模块的用户运行“perldoc Foo”来获取 你的模块的文档,它将读取在Foo.pm中找到的文档。用户的 如果这些文档描述了一个名为“Bar。”的包,那就会感到困惑。
即使您的模块是“纯”OO并且不导出任何内容,请执行以下操作 既定的惯例有助于避免混淆 - 想象一下维护 程序员从现在开始查看你的脚本,看到这个:
use Foo; my $bar = Bar->new();
在Foo.pm。
中看到一个类Bar是不太直观的所以不,理论上不需要它。但命名它们的惯例 同样如此广泛,在实践中它真的更多或 不太需要。
因此,似乎每个模块有多个包,只有与文件共享同名的包可以导出其变量/函数。如果您要为其他软件包(?)创建自己的导入功能,我怀疑您可以使用它。
无论如何,在我的例子中,如果我不想调用包整个层次结构树,我可以设置lib:
use lib './FOO/BAR';
use Foobar qw/foo/; # instead of "use FOO::BAR::Foobar"
这意味着我仍然可以Foobar.pm
并且package Foobar
而不是package FOO::BAR::Foobar