4

私の Moose クラスは、変更が許可されていないロールを使用しています。そのロールは、デフォルトで属性を定義します。クラスにその属性が必要ですが、デフォルトが異なります。

それは可能ですか?

私が思いついたのは、次のように、「新しい」メソッドを独自のコードで囲むことだけです。

around new => sub {
    my ($orig, $self) = (shift, shift);
    return $self->$orig(@_, the_attribute => $new_value);
}

しかし、周囲の new が有効かどうかはわかりません。また、よりエレガントなものを望んでいました。

4

2 に答える 2

8

より良い、より簡単な方法は、クラスでこれを書くことです:

has '+the_attribute' => (
    default => sub{1},
}

has+使用すると、属性の特定のプロパティのみをオーバーライドできます。

周囲の BUILDARGS よりもはるかに単純です。

于 2013-03-10T22:53:15.267 に答える
4

あなたは正しい考えを持っていますが、オーバーライドするべきではありませんnewMoose::Manual::BestPractices言います:

new をオーバーライドしない

オーバーライドnewは非常に悪い習慣です。代わりに、BUILDまたはBUILDARGSメソッドを使用して同じことを行う必要があります。をオーバーライドするnewと、クラスが不変になると Moose はコンストラクターをインライン化できなくなります。

これを行ってからしばらく経ちましたが、次の方法でうまくいくと思います。

around BUILDARGS => sub {
   my $orig  = shift;
   my $class = shift;
   return $self->$orig(
      the_attribute => $new_value,
      @_ == 1 ? %{ $_[0] } : @_,
   );
};

ノート:

  • 新しい属性を最初に配置して、オーバーライドできるようにしました。
  • 私はそれを両方->new({ ... })とも作りましたが、->new(...)それでも機能します。壊れることを気にしない場合は、@_代わりに使用できます。@_ == 1 ? %{ $_[0] } : @_->new({ ... })
于 2013-03-10T18:36:25.990 に答える