# 親クラス(ダイナミック・ローダー)
package Sample::DynamicLoad;
use strict;
# 以下の3つは手抜きモジュールです
use Readonly; # 変数の参照制限
use Class::Inspector; # クラスの検査を行う
use UNIVERSAL::require; # use, require の拡張
use vars qw/$AUTOLOAD/;
Readonly my $MODULE_PREFIX => __PACKAGE__ . '::';
sub new {
bless {}, shift
}
sub AUTOLOAD {
my $self = shift;
(my $dynamic = $AUTOLOAD) =~ s/.*://;
return if $dynamic eq 'DESTROY';
$self->autouse($dynamic)->new # コンストラクタが new であれば成功します
}
sub autouse {
my ($self, $dynamic) = splice @_, 0, 2;
$dynamic =~ s/(?:^|_)(.)/uc($1)/ge;
$dynamic = $MODULE_PREFIX . $dynamic;
unless (Class::Inspector->loaded($dynamic)) {
$dynamic->use or die "can't find module : $dynamic"
}
$dynamic
}
# 子モジュールのベースとなるクラス
package Sample::DynamicLoad::LoadBase;
sub new {
bless {}, shift
}
# 子モジュールその1
package Sample::DynamicLoad::Test;
use base qw/Sample::DynamicLoad::LoadBase/;
sub test {
print __PACKAGE__ . "->test!!\n"
}
# 子モジュールその2
package Sample::DynamicLoad::DynamicTest;
use base qw/Sample::DynamicLoad::LoadBase/;
sub test {
print __PACKAGE__ . "->test!!\n"
}
# メインルーティン
package Main;
my $sample = Sample::DynamicLoad->new;
# sample オブジェクトに対して、サブモジュール「Test」を要求。
# 続いてサブモジュールの「test」メソッドを呼び出します
$sample->test->test;
# sample オブジェクトに対して、サブモジュール「DynamicTest」を要求。
# 続いてサブモジュールの「test」メソッドを呼び出します
$sample->dynamic_test->test;
1