Mouseで「あるメソッドを持ったオブジェクト」という制約をつくる
互いに継承関係がなくてもRoleを適用していなくても duck_type()
を使えばOK!しかも自前で can()
するより高速なスグレモノ*1。
use strict; use warnings; package Foo { use Mouse; sub x { 1 } __PACKAGE__->meta->make_immutable(); } package Bar { use Mouse; sub x { 2 } __PACKAGE__->meta->make_immutable(); } package Baz { use Mouse; __PACKAGE__->meta->make_immutable(); } package Main; use Mouse; use Mouse::Util::TypeConstraints; duck_type 'MyApp.TypeWithFoo' => [qw(foo)]; # named type constraint has obj => ( is => 'rw', isa => duck_type([qw(x)]), # anonymous type constraint ); my $m = Main->new(); $m->obj(Foo->new); # OK $m->obj(Bar->new); # OK $m->obj(Baz->new); # NG: Attribute (obj) does not pass the type constraint because: Baz is missing methods 'x'
Mooと違ってサブルーチンを直接isaに指定することは出来ないのですが*2、type constraintはそこそこ使いやすいので慣れれば問題にならないと思います。