Perl6 MOPでRoleのメソッドを修飾する

perl6レッスン22日目の続き http://perl6advent.wordpress.com/2010/12/22/day-22-the-meta-object-protocol/

挨拶をする役割


role Aisatsu {
method aisatsu() {
say "お早う";
}
}

挨拶をする隣人


class Rinjin does Aisatsu {
method owakare() {
say "じゃ~ね";
}
}

隣人さん誕生


my $r=Rinjin.new;

役割のメソッド


$r.aisatsu;
お早う

クラスのメソッド


$r.owakare;
じゃ~ね

ラッパーを作る


my $wrapper=RoleHOW.new;

挨拶Roleのメソッドを修飾


for Aisatsu.new.^methods -> $method {
$wrapper.^add_method($method.name,
method (|$capture) {
# 名前をつけて挨拶する
print "クマさん、 ";
nextsame;
}
);
}

$wrapper.^compose();

'だれそれ does 役割' で「だれそれ」が「役割」を果すようになる。


$r does $wrapper;

修飾したRoleじゃなくてクラスのメソッド


$r.owakare;
じゃ~ね
これはいじってないから変らない。


$r.aisatsu;
クマさん、 クマさん、 クマさん、 クマさん、 お早う
あれ? role Aisatsuにはaisatsu以外に色々なメソッドがあって、それら全てをラップしてしまったようだ。


for Aisatsu.new.^methods.pick(5) -> $method {
say $method.name;
}
aisatsu
can
isa
does
list
ACCEPTS
Str
...

このcanとかisaのようなRole組み込みのメタメソッドが呼ばれて、その度にユーザ定義のラッパーコードが実行されちゃっているようだ。$wrapper.^add_method('aisatsu', ...)としておけば問題ないだろう。