Mouseでの非Moose/Mouseクラスの継承法

| コメント(0) | トラックバック(2)

MouseにはMouse::Meta::Class::new_objectメソッドがない(Class::MOPに頼っていないので当然ですが)ので、非Moose/Mouseクラスの継承の方法が限られます。従って、委譲での継承をすることになります。

追記:委譲でなく真っ当な継承を行う方法を、トラックバックで教えていただきました。委細は以下の通りです。

駄目な例

Moose::Cookbook::Basics::Recipe12の通りで、MooseをAny::Mooseに変えただけですが、これでは動きません。

package Foo;

use Any::Moose;

extends (
    'DateTime',
    any_moose('::Object'),
);

no Any::Moose;

sub new {
    my $class = shift;

    my $self = $class->SUPER::new(@_);

    return $class->meta->new_object(
        __INSTANCE__ => $self,
        @_,
    );
}

後になってググってみたところ、id:magicalhatさんのふしぎなぼうしMoose / Mouse を利用していないクラスを継承して、Moose / Mouse を利用した新しいクラスを作りたいCommentsAdd Star という記事の存在を知りました。しかし、Mouseでは現状は動きません(動いたというのは、「実は%INCMooseがいたからだ」というオチかもしれない、と想定しています)。

例えば以下のようにコンストラクターを呼んでも、

my $foo = Foo->new(year => 2009, month => 7, day => 7);

以下のようなエラーが出ます。

Can't locate object method "new_object" via package "Mouse::Meta::Class" at ...

なお、これは本稿の論旨とは少し離れますが、

__PACKAGE__->meta->make_immutable;    # any_moose('::Object')継承時には不可

という点も忘れがちなので、Moose::Object/Mouse::Object継承時には気を付けよう思います。

正しい例

さて、ということでもう片方の実装法に頼ることになりました。

use Any::Moose;

has '_datetime' => ( # 頭に_を付けて、内部使用アトリビュートであることを自己説明する
    is          => 'rw',
    isa         => 'DateTime',
    handles     => [qw(
        # 色々
    )],
);

no Any::Moose;
__PACKAGE__->meta->make_immutable;

# 後はどう実装しようが勝手ですが、一例として......。
# DateTimeの他のコンストラクタも適宜面倒を見てあげる必要があると思います
sub BUILDARGS {
    my ($class, %option) = @_;

    return { _datetime => DateTime->new(%option) };
}

これも結局は委譲を使った普通の方法ですが、ともあれ選択肢の幅が少しだけ狭まるということは覚えておきます。このためだけにMouseを諦めるのは勿体ないので、素直に委譲した方が後々楽だと思います。

id:magicalhatさんの疑問に自分なりの浅はかな考えを書きますと、「Moose/Mouseに慣れるとそうでないオブジェクト操作がまどろっこしくなるので、どうせ継承するならMoose/Mouseクラスとして継承してしまえ」という思いが日に日に増しているところです。何事も適材適所ですし、

  1. 初心者は使うことを知る
  2. 中級者は敢えて使わないことを知る
  3. 上級者は使い分けを知る(使うべきでない場所を知る)

という段階では私はまだ初心者だと自覚しているところです。

追記:真・継承法

追記:ちゃんと委譲でなしに継承で実装する方法を、id:magicalhatさんのふしぎなぼうし新しい記事によるトラックバックで教えていただきました。__PACKAGE__->meta->make_immutable(inline_constructor => 0);を使い、自前ではnewを実装しないことで、当初の野望を実現できます。どうもありがとうございました!

トラックバック(2)

非Moose/MouseクラスのMouseでの継承の例として、Email::Addressを委譲するサンプルコードを紹介します。 続きを読む

http //d.hatena.ne.jp/magicalhat/20090417/1239943579:Moose / Mouse を利用していないク... 続きを読む

コメントする

筆者"Gardejo"について

  • Twitter: @gardejo
  • GitHub: gardejo
  • CodeRepos: gardejo
  • CPAN: MORIYA

このサイトについて

Eorzea System Worksは、架空のシステム開発結社です。

FF14.name (FinalFantasyXIV.name)では、アヴァター(プレイヤーキャラクター)の管理システムやイベント出欠・リマインダシステムや、リンクシェル(LS)運営・管理システムやDKPシステムなどを設計・開発・公開する予定です。

関連サイト

関連サイトでは、他にもFF14に関連するサイトをいくつか紹介しています。

リンク, トラックバック歓迎

このブログへのリンク(どのページでも構いません)やトラックバックを歓迎します。

設計・開発・運用の参考にさせていただきますので、コメントもお気軽にお寄せください!

個別の記事に対するご意見などのほか、目安箱もご用意しています。

このブログ記事について

このページは、Gardejoが2009年7月 1日 01:20に書いたブログ記事です。

ひとつ前のブログ記事は「Mooseドキュメント日本語訳に注目」です。

次のブログ記事は「Mouseでの非Moose/Mouseクラスの継承法(Email::Addressでの例)」です。

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

2014年2月

            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28  

やや真面目なサイト