我有这个父模块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"。我假设导出的函数也应该可以被子模块访问,这也扩展了父类。我做错了什么。
答案 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。
这适合我自己的需要。