首页 > 解决方案 > 无法正确使用 Exporter

问题描述

我已经在包含语句的更大代码块上浪费了很多天Exporter,这在大约一年前曾经可以工作。这方面的几个变体都失败了,包括一个安装./FOO/BAR/Foobar.pm成功的信号。

我正在使用为 MSWin32-x64-multi-thread 构建的 Windows 10,Perl v5.26.0

调用者.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 "done\n";

./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 "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吗?但是如何跨模块链接功能呢?

标签: perlexporter

解决方案


出了三件事:

  1. FOO::BAR::Foobar::foo():没有sub,只有Foobar::foo()

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

  3. With foo():您使用@EXPORT_OK而不是@EXPORT,这意味着您需要显式 import 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:而不是继承 via @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;

推荐阅读