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なこんなモジュールないのかしらね。