asin:4873113148
PERL HACKS
(日本語版)
[英語版]

こういうものこそ、Module::Compile

self-0.11なるものを触ってみた - Unknown::Programming
なんとまあ悲惨な結果になりました。他かだか1000ループでコレではちょっと使い物にならないかなぁ・・・。
#!/usr/local/bin/perl
use strict;
use warnings;
use Foo;
my $f = Foo->new();
$f->foo("bar");
print $f->foo;
Foo.pm
package Foo;
use strict;
use warnings;
sub new { bless {}, shift }
use Self::Compile;
sub foo {
    $self->{foo} = shift if @_;
    $self->{foo};
}
1;
Self/Compile.pm
package Self::Compile;
use strict;
use warnings;
use Module::Optimize -base;
our $RE_IDENT = qr/[^\W\d]\w*/;

sub pmc_compile {
    my ($self, $src) = @_;
    $src =~ s{
                sub \s* ($RE_IDENT .*? \{)
            }{sub $1 my \$self = shift;}gxs;
    $src;
}
1;

Foo.pmFoo.pmcにコンパイルされます。

# Generated by Self::Compile 0 (Module::Compile 0.20) - do not edit!
################((( 32-bit Checksum Validator III )))################
#line 1
BEGIN { use 5.006; local (*F, $/); ($F = __FILE__) =~ s!c$!!; open(F)
or die "Cannot open $F: $!"; binmode(F, ':crlf'); if (unpack('%32N*',
$F=readline(*F)) != 0x047B041E) { use Filter::Util::Call; my $f = $F;
filter_add(sub { filter_del(); 1 while &filter_read; $_ = $f; 1; })}}
#line 1
package Foo;
use strict;
use warnings;
sub new { bless {}, shift }
sub foo { my $self = shift;
    $self->{foo} = shift if @_;
    $self->{foo};
}
1;

そして実際に実行されるのはFoo.pmcの方なので、パフォーマンスペナルティーはほとんど0です。Audreyってこういう黒魔術を見つけるのがうまいよなあ。そしてIngyが実装しているというまさにSufficiently Advanced Technology.

このテクニックとPerl HacksのHack #95を組み合わせると、Perlで

sub method($self, $arg){
  $self->{method} = $arg if defined $arg;
  $self->{method};
}

なんて具合に引数にパラメターをつけたりも出来ます。

Enjoy!

Dan the Perl Monger