題名¶
Moose::Cookbook::Extending::Recipe2 - オブジェクトのベースクラス用のロールを用意する
概要¶
package MooseX::Debugging;
use Moose::Exporter;
Moose::Exporter->setup_import_methods;
Moose::Exporter->setup_import_methods(
base_class_roles => ['MooseX::Debugging::Role::Object'],
);
package MooseX::Debugging::Role::Object;
use Moose::Role;
after 'BUILD' => sub {
my $self = shift;
warn "Made a new " . ref $self . " object\n";
};
本文¶
この例では、オブジェクトのベースクラス用のロールを用意して、簡単なデバッグ用の出力を追加します。このロールは、オブジェクトを生成するたびにそのオブジェクトの種類を知らせる警告を吐きます。
もちろん本物のデバッグ用ロールではもっと興味深いことをするものですが、このレシピで大切なのはこのロールをどう組み込むかということだけです。
今回は、Moose::ExporterとMoose::Util::MetaRoleを組み合わせて、モジュールがuse MooseX::Debugging
したときにはかならずベースオブジェクトのクラスにデバッグ用ロールが自動的に組み込まれるようにしています。
いくつかのコードについてはもっと細かく見ていきましょう。
Moose::Exporter->setup_import_methods(
base_class_roles => ['MooseX::Debugging::Role::Object'],
);
これはMooseX::Debugging
パッケージにimport
メソッドを用意するものです。ここでは実際になにかをエクスポートするわけではないのでsetup_import_methods
にはパラメータを渡していませんが、import
メソッドがないと私たちのinit_meta
メソッドが確実に呼ばれることは保証できないのです。なおinit_meta
メソッド自体はbase_class_roles
オプションを指定することにより、setup_import_methods
によって自動的に生成されています。生成されたinit_meta
はMoose::Util::MetaRole::apply_base_class_rolesを呼び出します。
それから、私たちのinit_meta
メソッドにはこのような行があります。
Moose->init_meta(%options);
これはほとんどどんな拡張モジュールでも使う決まり文句のようなものです。こうしておくと、呼び出し元のクラスにトレートを追加する「前」に通常のMooseのメタクラスを確実に用意できるようになります。
Moose->init_meta
メソッドを使えば確実に呼び出し元のクラスにまともなメタクラスを用意できますが、拡張モジュールの中ではそのロジックを繰り返したくはありません。Moose->init_meta
がすでに呼ばれていた(呼び出し元のクラスが私たちの拡張モジュールをuseする前にuse Moose
していた)場合、2度目のMoose->init_meta
は実質的には無効になります。
作者¶
Dave Rolsky <autarch@urth.org>
コピーライト & ライセンス¶
Copyright 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.