クラスメソッドのインポートをModule::Compileでやっちゃう。
ふーむ。
use Import qw(FormValidator::Simple#check as Validate);とすると、FormValidator::Simple->check() を呼び出す Validate関数 を定義してくれる Import.pm ってのを考えてみました。
http://www.fs-output.com/rintaro/2007/09/import-class-method.html
もういっそのことコードフィルターにしちゃえー、とか思いついたんだけどどーかな?
ってことでさっそく作ってみた。ネーミングはとりあえずFilter::ClassMethod。
package Filter::ClassMethod; use strict; use warnings; use Module::Compile -base; sub pmc_compile { my ( $class, $source, $extra ) = @_; my $vars = do { ( my $vars = $extra->{use} ) =~ s/^\s*use\s+Filter::ClassMethod\s*//; unless ( $vars =~ /;\s*$/ ) { $vars .= $1 if $source =~ s/([^;]*);//s; } eval "$vars"; }; die "error evaluating vars on use line ($extra->{use}): $@" if $@; my $funcs = join '|' , sort { $b cmp $a } keys %$vars; $source =~ s{(\s*use\s+)?([^A-Za-z0-9:]*)($funcs)([^A-Za-z0-9:]*)}{ my $use = $1; my $be = $2; my $af = $4; my $func = $3; if ( $use ) { $use.$be.$func.$af; } else { my $class = shift @{$vars->{$func}} || die 'class not found.'; my $method = shift @{$vars->{$func}} || 'new'; $be."${class}->$method".$af; } }ge; return $source; } 1;
これを使えばあら不思議、
use strict; use warnings; use Filter::ClassMethod { Validate => [qw/FormValidator::Simple check/], Foo => [qw/Foo/], }; use FormValidator::Simple; use CGI; use Foo; Validate( CGI->new,[] ); Foo();
このように書くだけで初コンパイル時に置換してくれちゃいます。
しかも単なる置換なので関数呼び出し時のスピードも気にする必要まったく無し!!!
・・・ま、ネタってことで。
追記:
コードがちょいミスってたorz
アップした後に間違いに気付く法則。マーフィーってやつ?