假设我想要一个这样的课程:
package Restraint;
use Moose;
has ball => (
is => 'ro',
does => 'Heavy',
);
has chain => (
is => 'ro',
does => 'Lockable',
);
has ball_class => (
is => 'ro',
isa => 'Str',
);
has chain_class => (
is => 'ro',
isa => 'Str',
);
1;
现在我想实例化类:
my $r = Restraint->new(
ball_class = 'Ball',
chain_class = 'Chain',
);
这两个论点都是强制性的。
我还想在构造期间实例化ball_class
和chain_class
,并将它们分配给相应的属性,以便最终我可以例如$r->ball->lift
或$r->chain->lock
等。
我该怎么做?
答案 0 :(得分:3)
只需将它们标记为“必需” - 请参阅Moose :: Manual :: Attributes
但是,对于“球”或“链”,这不会做任何事情。没有联系。
您可以使用惰性构建器设置球/链,这些构建器将引用您的类名(请再次参阅Moose手册)。
我可能只需要制作所需的对象并直接传递它们:
my $r = Restraint->new(
ball => CannonBall->new(...),
chain => IronChain->new(...)
);
好的 - 您不想传入对象。在这种情况下,你需要懒惰的构建器。将球标记为懒惰并给它一个建造者,当球首次使用时,穆斯将召唤建造者。
http://metacpan.org/pod/Moose::Manual::Attributes
http://metacpan.org/pod/Moose::Cookbook::Basics::Recipe3
请花些时间阅读moose文档 - 这里有很多文档,但编写得很好并且涵盖了很多功能。很多例子。
package Restraint;
use Moose;
has ball => (
is => 'ro',
does => 'Heavy',
lazy => 1,
builder => '_build_ball'
);
has ball_class => (
is => 'ro',
required => 1
);
sub _build_ball {
my $self = shift;
my $ball_class = $self->ball_class;
return $ball_class->new();
}
答案 1 :(得分:1)
仅在required
属性设置*_class
时使用BUILD
进行实例化似乎在某种程度上有效,除了:
ball
和chain
读写代码:
package Restraint;
use Moose;
has ball => (
is => 'rw',
does => 'Heavy',
);
has chain => (
is => 'rw',
does => 'Lockable',
);
has ball_class => (
is => 'ro',
isa => 'Str',
required => 1,
);
has chain_class => (
is => 'ro',
isa => 'Str',
required => 1,
);
sub BUILD {
my $self = shift;
my $ball = $self->ball_class->new();
$self->ball( $ball );
my $chain = $self->chain_class->new();
$self->chain( $chain );
}
1;
现在这不是一个很大的牺牲,但我仍然想知道是否有更正确的方法。