題名¶
Moose::Cookbook::Extending::Recipe3 - 別のベースオブジェクトクラスを用意する
概要¶
package MyApp::Base;
use Moose;
extends 'Moose::Object';
before 'new' => sub { warn "Making a new " . $_[0] };
no Moose;
package MyApp::UseMyBase;
use Moose ();
use Moose::Exporter;
Moose::Exporter->setup_import_methods( also => 'Moose' );
sub init_meta {
shift;
return Moose->init_meta( @_, base_class => 'MyApp::Base' );
}
本文¶
よくある拡張モジュールとしては、ベースクラスの代用品を提供するものがあります。MyApp::Base
を用意して、アプリケーションのすべてのクラスにextends 'MyApp::Base'
を追加するのもひとつのやり方ですが、これはかなり面倒です。そのかわりにMyApp::Base
をベースオブジェクトクラスにしてくれるMooseもどきのモジュールを作りましょう。
そうすれば、use Moose
と書くかわりにuse MyApp::UseMyBase
と書くことができるようになります。
この例のベースクラスは新しいオブジェクトを生成するたびにデバッグ用の情報を出力しますが、みなさんが自分でベースクラスを作るときはもっとおもしろい使い方を考えてみてください。
ここではMoose::Exporterの魔法を利用します。Moose::Exporter->setup_import_methods( also => 'Moose' )
を呼ぶと、import
メソッドとunimport
メソッドを用意してくれます。also => 'Moose'
の部分は、Mooseがエクスポートするものはすべてエクスポートしてほしい、という意味です。
ここで作成されたimport
メソッドは、私たちのinit_meta
メソッドを呼び出し、for_caller => $caller
という引数を渡します。この$caller
は、実際にはじめてimportを実行したクラスになります。
Moose::ExporterのAPIについてはMoose::Exporterのドキュメントをご覧ください。
MyApp::UseMyBaseを使う¶
実際に私たちの新しいベースクラスを使いたいときは単にMoose
の「かわり」にMyApp::UseMyBase
をuseしてください。これで、Mooseのすべてのシュガー関数と、私たちの新しいベースクラスが利用できるようになります。
package Foo;
use MyApp::UseMyBase;
has 'size' => ( is => 'rw' );
no MyApp::UseMyBase;
まとめ¶
単純なベースクラスだったわりにはずいぶん大げさな魔法を使いましたが、ベースクラスを拡張するモジュールにはよくメタクラスのトレートを合成したくなるものですし、そのような時にはこのテクニックが役に立ちます。
作者¶
Dave Rolsky <autarch@urth.org>
コピーライト & ライセンス¶
Copyright 2006-2009 by Infinity Interactive, Inc.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.