重新提出的问题 - 抱歉,这有点长.
例如,有一个简单的包
package My;
use Moose;
use namespace::sweep;
sub cmd1 {1}
sub smd2 {2}
__PACKAGE__->meta->make_immutable;
1;
Run Code Online (Sandbox Code Playgroud)
我希望允许My其他方法扩展其他方法,例如
package My::Cmd3;
use Moose;
extends 'My';
sub cmd3 {3}
1;
Run Code Online (Sandbox Code Playgroud)
这允许使用"基础" My和My::Cmd3下一个方法:
use My::Cmd3;
my $obj = My::Cmd3->new();
say $obj->cmd1(); #from the base My
say $obj->cmd3(); #from the My::Cmd3;
Run Code Online (Sandbox Code Playgroud)
但这不是我想要的.我不想use My::Cmd3;,(这里会有更多扩展包),我想要use My;.
使用角色是NICER,如:
package My;
use Moose;
with 'My::Cmd3';
sub cmd1 {1}
sub cmd2 {2}
__PACKAGE__->meta->make_immutable;
1;
package My::Cmd3;
use Moose::Role;
use namespace::autoclean;
sub cmd3 {3};
no Moose::Role;
1;
Run Code Online (Sandbox Code Playgroud)
这让我:
use My;
my $obj = My->new();
say $obj->cmd1();
say $obj->cmd3(); #from the role-package
Run Code Online (Sandbox Code Playgroud)
但是当有人制作My::Cmd4遗嘱时需要更改基础My包添加with My::Cmd4.(
我正在寻找一种方法,如何实现下一步:
use My;
#and load all needed packages on demand with the interface like the next
my $obj = My->new( commands => [qw(Cmd3 Cmd4)] );
#what should load the methods from the "base" My and from the wanted extensions too
say $obj->cmd1(); # from the base My package
say $obj->cmd3(); # from the "extension" package My::Cmd3
say $obj->cmd4(); # from the My::Cmd4
Run Code Online (Sandbox Code Playgroud)
所以,我现在拥有的:
package My;
use Moose;
has 'commands' => (
is => 'rw',
isa => 'ArrayRef[Str]|Undef', #??
default => sub { undef },
);
# WHAT HERE?
# need something here, what loads the packages My::Names... based on the supplied "commands"
# probably the BUILD { ... } ???
sub cmd1 {1}
sub smd2 {2}
__PACKAGE__->meta->make_immutable;
1;
Run Code Online (Sandbox Code Playgroud)
设计正确的对象层次结构是我永恒的问题..;(
我绝对肯定,这不应该是一个大问题,只需要一些我应该学习的指针; 因此很高兴知道一些CPAN模块,使用这种技术的...
所以问题:
My例如" My::Base并按需加载按需My::Something或是否应保留在My?为什么?my $obj = My->new(....);
my @methods = $obj->meta->get_all_methods();
Run Code Online (Sandbox Code Playgroud)
这只是Moose,我不能使用更小的东西Moo,对吗?
Ps:对于极长的问题再次抱歉.
第一:继承
使用 Moo 或 Moose 是一项超级简单的任务:
package My::Sub3;
use Moo;
extends 'My';
sub cmd3 {3}
1;
Run Code Online (Sandbox Code Playgroud)
第二:动态对象构建。定义构建函数并在运行时加载正确的模块。有几种方法可以做到这一点,我喜欢Module::Load CPAN 模块:
use Module::Load;
sub my_factory_builder {
my $class_name = shift;
load $class_name;
return $class_name->new(@_);
}
Run Code Online (Sandbox Code Playgroud)
然后,在您的代码中:
my @new_params = ();
my $object = my_factory_builder('My::Sub3', @new_params);
Run Code Online (Sandbox Code Playgroud)