ANONクラスの生成

ANONクラスを作りまくりたくなったのですが
Class::MOPを使ってもいいし
Moose::Meta::Class->create_anon_classとMooseつかってもいいんですけど、
ちょっと適当に作ってみた。

package Class::Anon;
use strict;
use warnings;

sub create_anon_class_by_eval {
    my ($class, $pkg, $base) = @_;

    eval qq|
        package $pkg;
        use strict;
        use warnings;
        use base '$base';
        1;
    |;
    die "can't create row_class : $pkg $@" if $@;

    return $pkg;
}

sub create_anon_class_by_isa {
    my ($class, $pkg, $base) = @_;

    { 
        no strict 'refs'; 
        @{"$pkg\::ISA"} = $base;
    }
    return $pkg;
}

'no Moooooooose';

evalしてやってもいいしISAをふがふがしてもつくれる。
test code:

use strict;
use warnings;
use Class::Anon;
use Test::Declare;

plan tests => blocks;

describe 'Class::Anon test' => run {
    test 'create_anon_class_by_eval' => run {
        my $anon_class = Class::Anon->create_anon_class_by_eval('Japan::Kyoto','Japan');
        is $anon_class, 'Japan::Kyoto';
        is $anon_class->me, 'japan';
        my $obj = $anon_class->new;
        isa_ok $obj, 'Japan';
    };
    test 'create_anon_class_by_isa' => run {
        my $anon_class = Class::Anon->create_anon_class_by_isa('Japan::Kanagawa','Japan');
        is $anon_class, 'Japan::Kanagawa';
        is $anon_class->me, 'japan';
        my $obj = $anon_class->new;
        isa_ok $obj, 'Japan';
    };
};

package Japan;
sub new { bless {}, shift }
sub me { 'japan' }

ベンチマーク:

use strict;
use warnings;
use Benchmark;
use Class::Anon;

timethese(10000, {
    create_anon_class_by_eval => sub {Class::Anon->create_anon_class_by_eval('Japan::Kyoto','Japan')},
    create_anon_class_by_isa  => sub {Class::Anon->create_anon_class_by_isa('Japan::Kanagawa','Japan')},
});

package Japan;
__END__
Benchmark: timing 10000 iterations of create_anon_class_by_eval, create_anon_class_by_isa...
create_anon_class_by_eval:  3 wallclock secs ( 0.74 usr +  0.01 sys =  0.75 CPU) @ 13333.33/s (n=10000)
create_anon_class_by_isa:  0 wallclock secs ( 0.02 usr +  0.00 sys =  0.02 CPU) @ 500000.00/s (n=10000)
            (warning: too few iterations for a reliable count)

まあ当然evalした方が遅いですが。

no Moooseなこんなモジュールないのかしらね。