下記ですが、Moose 0.65で直ってますよ!


MooseでRoleを作ります
package Role; use Moose::Role; requires 'foo'; no Moose;
で、このRoleをChildで実装しますが、こいつに親クラスParentがあると仮定します。こんな感じ。
# Parent package Parent; use Moose; has 'foo' => ( is => 'rw', isa => 'Int' ); no Moose; # Child package Child; use Moose; extends 'Parent'; with 'Role'; no Moose;
で、foo()ってattributeがついているんだから、当然Roleのrequiresも満たしてると思いますよね? 満たしてません。

実はMoose::Roleのrequiresによって作成される制限はMoose自身のhasをrequiresの条件を満たす物として認識できないようです。これは既知。なので、以下のようにoverrideしてやる必要があります:
package Child; use Moose; extends 'Parent'; override 'foo' => sub { super() }; with 'Role'; no Moose;
ちなみにnew()で色々と魔法を追加したい場合はaroundを使うといいわけですが、ここにも落とし穴があります。先ほどのParentでaround newをしてみます
package Parent; use Moose; has 'foo' => ( is => 'rw', isa => 'Int' ); around 'new' => sub { my ($next, $class, @args) = @_; # なんかごにょごにょ・・・ return $next->($class, @args); }; no Moose;
ChildはParentから継承しているんだから、Parent::new()およびそのaroundで指定された無名関数が呼ばれると思いますよね?ところがこのままではこのnew()は呼ばれません。

呼ばれるのはnew()から*明示的に*指定されたメソッドと、BUILDだけです。なので、このChildのnew()が呼ばれた時にParentのnew()を呼び出すには、こちらもまたoverrideを使う必要があります
package Child; use Moose; extends 'Parent'; override 'foo' => sub { super() }; override 'new' => sub { super() }; with 'Role'; no Moose;
というわけで皆さん気をつけてくださいね

カテゴリ

トラックバック(0)

このブログ記事に対するトラックバックURL: http://mt.endeworks.jp/cgi-bin/mt-tb.cgi/2144

コメントする

筆者

daisuke - a.k.a. "lestrrat", Perl hacker at Livedoor Inc, Japan Perl Association 代表理事

このブログ記事について

このページは、Dが2008年7月14日 11:28に書いたブログ記事です。

ひとつ前のブログ記事は「怒髪」です。

次のブログ記事は「Data::Valve Is Waaaay Faster Than Data::Throttler」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.1