題名¶
Moose::Cookbook::Roles::Recipe2 - 高度なロールの合成――メソッドの排除と別名
概要¶
package Restartable;
use Moose::Role;
has 'is_paused' => (
is => 'rw',
isa => 'Bool',
default => 0,
);
requires 'save_state', 'load_state';
sub stop { 1 }
sub start { 1 }
package Restartable::ButUnreliable;
use Moose::Role;
with 'Restartable' => {
-alias => {
stop => '_stop',
start => '_start'
},
-excludes => [ 'stop', 'start' ]
};
sub stop {
my $self = shift;
$self->explode() if rand(1) > .5;
$self->_stop();
}
sub start {
my $self = shift;
$self->explode() if rand(1) > .5;
$self->_start();
}
package Restartable::ButBroken;
use Moose::Role;
with 'Restartable' => { -excludes => [ 'stop', 'start' ] };
sub stop {
my $self = shift;
$self->explode();
}
sub start {
my $self = shift;
$self->explode();
}
本文¶
この例では、ロールのどのメソッドを取り込むを細かくコントロールするやり方を説明します。ここではRestartable
というロールを用意しました。これにはis_paused
というアトリビュートと、stop
とstart
という2つのメソッドがあります。
それから、もう2つ、インタフェースは同じですが、それぞれstop
メソッドとstart
メソッドにひねりを加えたロールを用意します。
Restartable::ButUnreliable
ロールではstop
とstart
の実装を新しくしつつ、もともとの実装も利用できるようにしたいので、Restartable
のメソッドに別名をつけてプライベートメソッドにし、もとのメソッドの方にラッパを用意することにします。(1)
with 'Restartable' => {
-alias => {
stop => '_stop',
start => '_start'
},
-excludes => [ 'stop', 'start' ]
};
Restartable::ButBroken
ロールの方では、stop
とstart
の振る舞いを一新したいので、Restartable::ButBroken
にRestartable
ロールを合成するときにstop
とstart
を完全に排除してしまいます。
-excludes
パラメータは、排除したいメソッドがひとつだけの場合は引数に単一の文字列を取ることができることも特記しておきます。
with 'Restartable' => { -excludes => [ 'stop', 'start' ] };
まとめ¶
排除と別名は強力なツールですし、特にほかのロールからロールを生成する場合には便利に使えます。この例では、すべてのロールがRestartable
ロールを実装しています。どのロールもAPIは同じですが、それぞれ裏では異なった実装になっています。
別名と排除の機能は、ロールをクラスに合成するときも使えます。
1¶
-
ラッパに言及したことからおわかりの通り、メソッドモディファイアを利用しても同じことができますが、この例ではそうしていません。
作者¶
Dave Rolsky <[email protected]>
コピーライト & ライセンス¶
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.