6

現在、基本クラスの 1 つを拡張するすべてのオブジェクトにビルダー メソッドを委譲しています。私が直面している問題は、すべてのオブジェクトがそれ自体の属性を読み取るか、値で渡される必要があることです。

#  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 の内部によって自動的に呼び出され、1 つの引数 (オブジェクト参照自体) のみが渡されます。$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 に答える