Perl导出到子模块

时间:2014-04-14 11:33:22

标签: perl moose

我有这个父模块MyApp.pm:

package MyApp;
use Moose;
use base 'Exporter';
our @EXPORT = qw(msg);
sub msg {
    print "Hello msg\n";
}
1;

由此子模块MyApp2.pm继承:

package MyApp2;
use Moose;
extends qw(MyApp);
1;

并且在App.cgi脚本中使用时如下:

#!/usr/bin/perl
use MyApp2;
msg();

我收到错误消息:

Undefined subroutine &main::msg called at App.cgi line 3.

因此导出的函数在子类MyApp2中不起作用,但仅在我使用"使用MyApp"而不是"使用MyApp2"。我假设导出的函数也应该可以被子模块访问,这也扩展了父类。我做错了什么。

2 个答案:

答案 0 :(得分:5)

继承仅更改方法调用的处理方式;函数调用或变量访问(如our @EXPORT)不受影响。

您可以将其用作方法,而不是导出函数:

use MyApp2;

MyApp2->msg;

但在这种情况下,显式加载MyApp以便导入msg函数,并额外加载MyApp2以加载此类会更清晰。

use MyApp;
use MyApp2;

msg;

通常建议模块面向对象或通过导出函数提供接口,但不能同时执行这两种操作。

答案 1 :(得分:0)

以下是我为我的请求找到的解决方案:

package MyApp;
use Moose;
use base 'Exporter';
our @EXPORT = qw(msg);

sub import {
my ($class, @args) = @_;
    my $caller = $class.'::';
    {
        no strict 'refs';
        @{$caller.'EXPORT'} = @EXPORT;
        foreach my $sub (@EXPORT) {
            next if (*{"$caller$sub"}{CODE});
            *{"$caller$sub"} = \*{$sub};
        }
    }
    goto &Exporter::import;
}

sub msg {
    print "Hello msg MyApp\n";
}
1;

这里的想法是将“@EXPORT”数组的所有内容导出到子模块中,只添加不存在的子类,因此不会覆盖子类中的任何方法。

在上面的示例中,这将从MyApp导出到子MyApp2。

这适合我自己的需要。