无法正确使用导出器

  • 本文关键字: perl exporter
  • 更新时间 :
  • 英文 :


我浪费了很多天在一个更大的代码块上,其中包含Exporter语句,这些代码块在大约一年前曾经工作过。对此的几种变体都失败了,包括安装./FOO/BAR/Foobar.pm,这标志着成功。

我正在使用Windows 10,Perl v5.26.0,为MSWin32-x64多线程构建

Caller.pl

#!/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 "donen";

./FOO/BAR/Foobar.pl

#!/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 "Loadedn";
$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吗?但是,如何跨模块链接功能呢?

有三件事出错:

  1. 有了FOO::BAR::Foobar::foo():没有这样的sub,只有Foobar::foo()

  2. 使用foo()use FOO::BAR::Foobar;等价于BEGIN { require FOO::BAR::Foobar; FOO::BAR::Foobar->import() },但是在包FOO::BAR::Foobar中没有可用的方法import,因为您要将Exporter继承到包Foobar中。

  3. 使用foo(): 你使用的是@EXPORT_OK而不是@EXPORT,这意味着你需要显式导入foo,但你没有在use FOO::BAR::Foobar;这样做。

因此,需要两件事来解决此问题:

  1. 正如@HåkonH ægland在评论中已经指出的那样,将package Foobar;更改为package FOO::BAR::Foobar;

  2. 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 "Loadedn";
$FOO = q{some val};
}
1;

相关内容

  • 没有找到相关文章

最新更新