2006年05月06日 22:30 [Edit]
perl - Yet Another Way to Add Singleton Methods
もちろん!
naoyaグループ - naoyaの日記 - Perl で Singleton Methodということで Class::SingletonMethod みたいにクラス名を汚染しちゃうような方法以外で Singleton Method (特異メソッド) を実現する方法はないかなあ。
賢明で懸命なヒョウ本(持ってない人は上から買ってちょんまげ)の読者は、これを思いつくと思うのだけど。
package Object::SingletonMethod;
use 5.008001;
use strict;
use warnings;
use Carp;
use Data::Dumper;
our $VERSION = '0.01';
our $DEBUG = 1;
my %Method;
sub singleton_method {
my $self = shift;
my ( $method, $subref ) = @_;
ref $subref eq 'CODE'
or croak '$obj->singleton_method(name => sub{...})';
$Method{ $self + 0 }{$method} = $subref;
}
sub can {
my ( $self, $method ) = @_;
my $subref = $Method{ $self + 0 }{$method};
return $subref if $subref;
return $self->SUPER::can($method);
}
sub DESTROY {
my $self = shift;
$DEBUG and carp "Destroing $self";
delete $Method{ $self + 0 };
}
sub AUTOLOAD {
my $self = shift;
my $method = our $AUTOLOAD;
$method =~ s/.*:://;
$DEBUG and carp "($self)->$method";
if ( my $subref = $Method{ $self + 0 }{$method} ) {
$subref->( $self, @_ );
}
else {
my $pkg = ref $self;
croak qq(Can't locate object method "$method" via package "$pkg");
}
}
1;
__END__
以下で実証。
#
use strict;
use warnings;
use Data::Dumper();
package Foo;
use base 'Object::SingletonMethod';
sub new {
my $class = shift;
bless {@_} => $class;
}
sub dump{
my $self = shift;
local ($Data::Dumper::Terse) = 1;
return Data::Dumper::Dumper($self);
}
package main;
my $foo = Foo->new;
my $far = Foo->new;
$foo->singleton_method(
inc => sub {
my $self = shift;
$self->{_inc}++;
$self;
}
);
$foo->inc;
$foo->inc;
print "foo can inc? ", ( $foo->can('inc') ? "Yes" : "No" ), "\n";
print "foo can new? ", ( $foo->can('new') ? "Yes" : "No" ), "\n";
print "foo can pee? ", ( $foo->can('pee') ? "Yes" : "No" ), "\n";
print "far can inc? ", ( $far->can('inc') ? "Yes" : "No" ), "\n";
print "far can new? ", ( $far->can('new') ? "Yes" : "No" ), "\n";
print "far can pee? ", ( $far->can('pee') ? "Yes" : "No" ), "\n";
print $foo->dump;
実はこの特定のmy variableに$object + 0をキーにしてインスタンスをしまい込むという方法は、Inside-Out Objectと呼ばれる、比較的新しいPerlのObject実装法で、これをDamian流に徹底的に昇華させたのがClass::Std。これ、いつか詳細解説(つーか添削!)するつもりだけど、待てない人はロングテールなワンコ本→をじっくりお読みあれ。
Dan the Man with Too Many Ways to Do Too Many Things
Posted by dankogai at 22:30│Comments(1)│TrackBack(2)
この記事へのトラックバックURL
この記事へのトラックバック
賢明で懸命なヒョウ本(持ってない人は上から買ってちょんまげ)の読者は、これを思いつくと思うのだけど。 ということで弾さんが教えてくれた方法を Class::Pluggable に反映してみた。 http://trac.bloghackers.net/browser/lib/perl/Class-Pluggable/trunk/lib/Class/Plug...
Class::Pluggable#4【naoyaの日記】at 2006年05月07日 01:43
Shiroさん、いい質問です。
404 Blog Not Found:perl - Yet Another Way to Add Singleton Methodsちょっと疑問。この実装で、$fooが不要になった時に$fooおよびシングルトンメソッドのsubの実体はGCされるのでしょうか。
perl - DESTROYって何?【404 Blog Not Found】at 2006年05月07日 11:33
この記事へのコメント
ちょっと疑問。この実装で、$fooが不要になった時に$fooおよびシングルトンメソッドのsubの実体はGCされるのでしょうか。
Posted by shiro at 2006年05月07日 06:02
