題名¶
Moose::Cookbook::Basics::Recipe6 - augment/innerの例
概要¶
package Document::Page;
use Moose;
has 'body' => ( is => 'rw', isa => 'Str', default => sub {''} );
sub create {
my $self = shift;
$self->open_page;
inner();
$self->close_page;
}
sub append_body {
my ( $self, $appendage ) = @_;
$self->body( $self->body . $appendage );
}
sub open_page { (shift)->append_body('<page>') }
sub close_page { (shift)->append_body('</page>') }
package Document::PageWithHeadersAndFooters;
use Moose;
extends 'Document::Page';
augment 'create' => sub {
my $self = shift;
$self->create_header;
inner();
$self->create_footer;
};
sub create_header { (shift)->append_body('<header/>') }
sub create_footer { (shift)->append_body('<footer/>') }
package TPSReport;
use Moose;
extends 'Document::PageWithHeadersAndFooters';
augment 'create' => sub {
my $self = shift;
$self->create_tps_report;
inner();
};
sub create_tps_report {
(shift)->append_body('<report type="tps"/>');
}
# <page><header/><report type="tps"/><footer/></page>
my $report_xml = TPSReport->new->create;
本文¶
このレシピではaugment
メソッドモディファイアの動作を紹介します。このモディファイアは通常のサブクラスから親クラスへというメソッド解決順序を逆転させるものです。augment
を使うと、「もっとも具体的でない(抽象的な)」メソッドがまず呼ばれ、inner
を呼ぶたびに継承ツリーをたどって、もっとも具体的なサブクラスで終わります。
augment
モディファイアを使って設計した親クラスは、具体的に拡張していくことができます(親クラスでは一般的なラッパ機能を用意し、サブクラスを使って詳細を詰めていきます)。
上の例では、ドキュメントクラスを一組作りました。もっとも具体的なものはTPSReport
です。
まずはもっとも具体的でないDocument::Page
から見ていきましょう。Document::Page
のcreate
メソッドにはinner()
の呼び出しがあります。
sub create {
my $self = shift;
$self->open_page;
inner();
$self->close_page;
}
このinner
はMoose
がエクスポートしている関数で、augment
されたメソッドで使えるsuper
のようなものです。inner
が呼ばれると、Mooseはチェーンの中から次のメソッドを探します(この場合はDocument::PageWithHeadersAndFooters
のaugment
モディファイア)。お気づきの通り、inner
はモディファイアの中でも呼べます。
augment 'create' => sub {
my $self = shift;
$self->create_header;
inner();
$self->create_footer;
};
すると、次の、もっとも具体的なモディファイアが見つかります(TPSReport
クラスのものです)。
最後、TPSReport
クラスでチェーンは終わりです。
augment 'create' => sub {
my $self = shift;
$self->create_tps_report;
inner();
};
もう一度inner
関数を呼んでいますが、これ以上具体的なサブクラスはありませんので、ここでは何もしません。この呼び出しを入れておくと、将来TPSReport
を簡単にサブクラス化できるようになります。
まとめ¶
augment
モディファイアは、ネストしたラッパを作成できる強力なツールです。始終必要になるものではありませんが、必要なときには非常に役に立ちます。
作者¶
Stevan Little <stevan@iinteractive.com>
Dave Rolsky <autarch@urth.org>
コピーライト & ライセンス¶
Copyright 2007-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.