前回の
動的なモジュールロードで実現できること
動的なモジュールロードをすると実現できることを紹介します。
コード量が少なくなる
ロードするモジュールの名前を動的に生成できるため,use
でモジュールロードする場合と比べて書く必要のあるコード量が少なくなります。
たとえば次のように,
use Module::Load qw( load );
for my $module_ name (qw/ Foo Bar /) {
load('MyApp::' . $module_ name);
}
動的なディスパッチ
コード量が少なくなることの中でも特筆すべき点として,
項目の多いマスタデータや,
具体的な利用例として,
データベースにある大量のアイテムデータと,
use Class::Load qw( load_class );
use String::CamelCase qw( camelize );
sub use {
my ($self, $user) = @_;
my $module =
'MyApp::ItemEffect::' . camelize($self->name);
load_class($module);
my $effect = $module->new(@_);
$effect->execute($user);
}
起動/ ロード時間の短縮
モジュールロードするタイミングを,Moo
,Type::Tiny,
など,
依存関係の動的な解決
依存関係を動的に解決できるので,
動的なモジュールロードの活用
これらの動的なモジュールロードで実現できることが,
コード量を少なくする
コード量を少なくするために活用されている事例を見てみましょう。
Module::Findの事例──特定の名前空間に属するモジュールをすべて読み込む
Module::Findは,usesub
で引数の名前空間直下に属するモジュールをロードし,useall
で引数の名前空間に属するモジュールを再帰的にロードします。
use Module::Find qw( usesub useall );
# Foo::Bar, Foo::Baz, ...
my @sub_modules = usesub('Foo');
# Foo::Bar, Foo::Bar::Hoge, Foo::Baz, etc...
my @all_modules = useall('Foo');
Catalystのコンテナ──use忘れを防ぎ, モジュール名を短縮する
CatalystというPerl製のWAFCatalyst
ではアプリケーションの起動時にすべてのモデルモジュールをロードし,use
忘れがなくなる,
実際にCatalyst
で作られたアプリケーションでどのようにモデルモジュールが使われるのかを見てみましょう。
package MyApp::Controller::Root;
use Moose;
use namespace::autoclean;
BEGIN { extends 'Catalyst::Controller' }
__PACKAGE__->config(namespace => '');
sub foo :Local :Args(1) {
my ($self, $c, $name) = @_;
my $country =
$c->model('DB::Countries') ―(1)
->search({ name => $name }); ―(2)
$c->stash(
template => 'foo.tt',
country => $country,
);
}
このコードはCatalyst
のコントローラのコードになります。
前述したとおり,
MyApp::Model::DB::Countries
のインスタンスを取得しています。
search
メソッドを呼び出しています。
Catalystのコンテナ機能と似た事例にモデルモジュール専用のモジュールローダがあり,Catalyst
とは別のWAFのプラグインなどで見受けられます。これは起動時にすべてのモデルモジュールのロードをするのではなく,