我浪费了很多天来处理更大的代码块,其中包含Exporter
语句,这些语句曾在大约一年前使用过。对此的一些变化失败了,包括安装了./FOO/BAR/Foobar.pm
,表示成功。
我使用的是Windows 10,Perl v5.26.0,专为MSWin32-x64多线程而构建
#!/usr/bin/perl
use lib ".";
use lib "./FOO/BAR";
use strict;
use warnings;
use FOO::BAR::Foobar;
print "try FOO::BAR::Foobar::foo()\n";
FOO::BAR::Foobar::foo(); # perl can't find this
print "try foo()\n";
foo(); # errors out - can't find &main::foo
print "done\n";
#!/usr/bin/perl -w
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;
perl Caller.pl
try FOO::BAR::Foobar::foo()
Undefined subroutine &FOO::BAR::Foobar::foo called at Caller.pl line 12.
发生了什么?我应该放弃使用Exporter
吗?但是,如何跨模块链接功能?
答案 0 :(得分:4)
有三件事情出错:
FOO::BAR::Foobar::foo()
:没有sub
,只有Foobar::foo()
。
使用foo()
:use FOO::BAR::Foobar;
相当于BEGIN { require FOO::BAR::Foobar; FOO::BAR::Foobar->import() }
,但是import
包中没有方法FOO::BAR::Foobar
,因为您将Exporter
继承到包Foobar
。
使用foo()
:您使用的是@EXPORT_OK
而不是@EXPORT
,这意味着您需要明确导入foo
,但您没有这样做那个在use FOO::BAR::Foobar;
。
因此需要做两件事来解决这个问题:
正如@HåkonHægland在评论中已经指出的那样,将package Foobar;
更改为package FOO::BAR::Foobar;
。
将use FOO::BAR::Foobar;
更改为use FOO::BAR::Foobar qw/foo/;
。
然后您展示的代码将起作用 - 无需放弃Exporter
。我建议使用Exporter
的不同风格:不要通过@ISA
继承,只需将import
导入包中即可。以下是我编写文件./FOO/BAR/Foobar.pm
:
package FOO::BAR::Foobar;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT_OK = qw(foo);
our $FOO;
sub foo {
print "Loaded\n";
$FOO = q{some val};
}
1;