6

我目前正在将构建器方法委托给扩展我的基类之一的所有对象。我面临的问题是我需要所有对象要么读取自身的属性,要么传入一个值。

#  In Role:
has 'const_string' => (
    isa     => 'Str',
    is      => 'ro',
    default => 'test',
);

has 'attr' => (
    isa     => 'Str',
    is      => 'ro',
    builder => '_builder',
);

requires '_builder';


#  In extending object  -  desired 1
sub _builder {
    my ($self) = shift;
    #  $self contains $self->const_string
 }

#  In extending object  -  desired 2
sub _builder {
    my ($arg1, $arg2) = @_;
    #  $args can be passed somehow?
 }

这是目前可能的还是我将不得不以其他方式做到这一点?

4

2 回答 2

12

您不能将参数传递给属性构建方法。它们由 Moose 内部自动调用,并且只传递一个参数——对象引用本身。构建器必须能够根据它在 中看到的$self内容或它有权访问的环境中的任何其他内容返回其值。

您希望将什么样的参数传递给构建器?您可以将这些值传递给对象构造函数并将它们存储在其他属性中吗?

# in object #2:
has other_attr_a => (
    is => 'ro', isa => 'Str',
);
has other_attr_b => (
    is => 'ro', isa => 'Str',
);

sub _builder
{
    my $self = shift;
    # calculates something based on other_attr_a and other_attr_b
}

# object #2 is constructed as:
my $obj = Class2->new(other_attr_a => 'value', other_attr_b => 'value');

另请注意,如果您有基于其他属性值构建的属性,则应将它们定义为lazy,否则构建器/默认值将在对象构造时立即运行,并且以未定义的顺序运行。将它们设置为惰性会延迟它们的定义,直到第一次需要它们。

于 2010-07-20T16:13:55.863 回答
0

你可以这样做:

has 'attr' => (
isa     => 'Str',
is      => 'ro',
builder => '_pre_builder',
);

sub pre_builder {
  _builder(@_, 'your_arg');
}
于 2016-03-22T15:09:35.090 回答