end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

どういう場合にAUTOLOADを使用するか?...未解決

perlではAUTOLOADという仕組みがあります。
sub AUTOLOADが定義されていると、呼び出し対象のmethodがない場合にこれが呼ばれます。

#!perl    #### in ActivePerl

use strict;
use warnings;

my $animal = Animal->new();
$animal->hogehoge();

package Animal;

sub new {
    my ($class) = @_;
    my $self = {};
    return bless $self, $class;
}

sub AUTOLOAD {
    our $AUTOLOAD;
    warn "$AUTOLOAD can't find in ",__PACKAGE__,"\n";
}

1;

このサンプルスクリプトを実行すると、次のように表示され、AUTOLOAD実行時の$AUTOLOADには、methodの完全修飾名が入っていることが分かります。

bash-3.2$ ./foo.pl 
Animal::hogehoge can't find in Animal
Animal::DESTROY can't find in Animal
bash-3.2$ 

DESTROY

また、サンプルスクリプトには記述しませんでしたが、オブジェクトが破棄される直前に呼ばれるDESTROYも実行されていることが分かります。

次に先程のサンプルスクリプトから sub AUTOLOADを削除して実行すると、次のように表示され、hogehoge メソッドのみがエラーとなることが分かります。

bash-3.2$ ./foo.pl 
Can't locate object method "hogehoge" via package "Animal" at ./foo.pl line 7.
bash-3.2$ 

AUTOLOADを使用するケースとは?

次のurlでもAUTOLOADに触れていますが、どうやら他のクラスdelegate(委譲)する場合に利用することができるようです。
http://naoya.dyndns.org/~naoya/mt/archives/000892.html

package ExtraDog;
 
sub new {
    my $class = shift;
    $self = bless {}, $class;
    $self->{_dog} = shift;
    $self;
}
 
sub AUTOLOAD {
    my $self = shift;
    (my $method = $AUTOLOAD) =~ s/.*://g;
    return if ($method eq 'DESTROY');
 
    print "(僕はその辺の犬とは違うんだ...) ";
    return $self->{_dog}->$method;
}
1;

では、どのような場合に委譲を利用するのだろう...