Mooseのwithってクラス名を省略できないのかな?

ちょっとした疑問。

Mooseでwithするときに、例えば

package MyClass;
use Moose;

with qw{
    FooFooFoo::BarBarBar::BazBazBaz::Role::Base
    FooFooFoo::BarBarBar::BazBazBaz::Role::Hoge
    FooFooFoo::BarBarBar::BazBazBaz::Role::Muge
    FooFooFoo::BarBarBar::BazBazBaz::Role::Pugera
    MooseX::Foo
    MooseX::Bar
};

みたいな感じになっててちょーメンドイ。

とりあえず

package MooseX::WithIn;
use strict;
use warnings;

sub import {
    my $pkg    = caller;
    my $with   = $pkg->can('with');
    my $code   = Class::MOP::subname('Moose::__with_in' => sub (@) {
        $with->(map { m{^\+(.+)} ? $1 : $pkg->with_prefix."::$_" } @_);
    } );
    no strict 'refs';
    no warnings 'redefine';
    *{"${pkg}::with"} = $code;
}

1;

package MyClass;
use Moose;
use MooseX::WithIn;

sub with_prefix { 'FooFooFoo::BarBarBar::BazBazBaz' }

with qw{
    Role::Base
    Role::Hoge
    Role::Muge
    +MooseX::Foo
    +MooseX::Bar
};

みたいな感じでやってるけどみんなどなんだろ?

Moose本来の機能で出来るかもしれないけどソースまだ全部追えてないからとりあえず自分で実装してみたんだ。

うほは。


ちなみにMyClass->meta->add_around_method_modifierのがスマートだろっていう突っ込みが入る前に言っておくと、withとかってClass::MOP経由で定義されたものではなく、あくまでExportで追加されたものなのでMOP系が使えないのです。

また、Class::MOP::subname使ってる理由はno Mooseした時に単なる関数リファだとwithが消えてくれないからです。

Mooseのunimport見てみたら元となる関数リファがMooseで定義されたものであるかどうかまでチェックしてるのでこんな感じになってます。



んー、実に興味深い(湯川学風に)。