无法正确使用Exporter

时间:2018-06-13 16:16:36

标签: 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 "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吗?但是,如何跨模块链接功能?

1 个答案:

答案 0 :(得分:4)

有三件事情出错:

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

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

  3. 使用foo():您使用的是@EXPORT_OK而不是@EXPORT,这意味着您需要明确导入foo,但您没有这样做那个在use FOO::BAR::Foobar;

  4. 因此需要做两件事来解决这个问题:

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

    2. use FOO::BAR::Foobar;更改为use FOO::BAR::Foobar qw/foo/;

    3. 然后您展示的代码将起作用 - 无需放弃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;