前回の
動的なモジュールロードで実現できること
動的なモジュールロードをすると実現できることを紹介します。
コード量が少なくなる
ロードするモジュールの名前を動的に生成できるため、useでモジュールロードする場合と比べて書く必要のあるコード量が少なくなります。
たとえば次のように、 コード量が少なくなることの中でも特筆すべき点として、 項目の多いマスタデータや、 具体的な利用例として、 データベースにある大量のアイテムデータと、 モジュールロードするタイミングを、 依存関係を動的に解決できるので、 これらの動的なモジュールロードで実現できることが、 コード量を少なくするために活用されている事例を見てみましょう。 Module::Findは、 CatalystというPerl製のWAF 実際に このコードは 前述したとおり、 Catalystのコンテナ機能と似た事例にモデルモジュール専用のモジュールローダがあり、 簡単にプラグインの実装と追加ができるようになるため、 例としてTengのプラグイン機構を簡略化したコードでプラガブルなアーキテクチャの実装方法を紹介します。 次に、 プラグインモジュールを利用するには、 モジュール本体で直接プラグインを利用すると、 プラグインを利用したならば、 動的なモジュールロードを活用すると、 例として、 MojoliciousはPerl製のWAFで、 このように動的なモジュールロードを活用すると、 <続きの 2022年8月24日発売use Module::Load qw( load );
for my $module_動的なディスパッチ
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の事例──特定の名前空間に属するモジュールをすべて読み込む
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ではアプリケーションの起動時にすべてのモデルモジュールをロードし、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とは別のWAFのプラグインなどで見受けられます。これは起動時にすべてのモデルモジュールのロードをするのではなく、プラガブルなアーキテクチャの実装──Tengの事例
Tengは軽量なO/Teng::Plugin::Countを使うと、プラグイン機構の実装
Tengのようなプラグイン機構は、@EXPORTで指定されたメソッド)package Module;
use Module::Load qw( load );
sub add_plugin {
    my ($class, $plugin) = @_;
    my $package = "Module::Plugin::${plugin}";
    load($package);
    {
        no strict 'refs';
        for my $method ( @{"${package}::EXPORT"} ){
            *{$class . '::' . $method} =
                $package->can($method);
        }
    }
}プラグインモジュールの実装
Module::Plugin::${プラグイン名}といった風に、@EXPORTに追加します。package Module::Plugin::Hoge;
our @EXPORT = qw( do_something );
sub do_something {
    my $class = shift;
    warn 'Do something';
}プラグインモジュールの利用
add_メソッドにプラグイン名を渡します。package My::Module;
use parent 'Module';
__PACKAGE__->add_plugin('Hoge');use My::Module;
My::Module->do_something();フレームワークの実装──Mojoliciousのルーティングの事例
package SomeWebApp;
use Mojo::Base 'Mojolicious';
# アプリケーション起動時に呼ばれるメソッド
sub startup {
    my $self = shift;
    my $r = $self->routes;
    $r->get('/')->to('Root#root'); ―(1)
    my $user =
        $r->any('/user')->to(controller => 'user'); ―(2)
    $user->post('/add/:name')->to(action => 'add'); ―(3)
}SomeWebApp::Controller::Rootクラスのrootメソッドを呼び出す指定をしています。/userにあらゆるメソッドでリクエストが来た際SomeWebApp::Controller::Userクラスのメソッドで処理することを指定しています。$user_にはその状態を保持したルーティングオブジェクトが格納されているので、SomeWebApp::Controller::Userクラスのどのメソッドで処理を行うかの指定をするだけで簡潔にリクエストに応じた呼び出す処理を割り当てることができます。/user/SomeWebApp::Controller::Userクラスのメソッドを指定しています。本誌最新号をチェック!
WEB+DB PRESS Vol.130
B5判/
定価1,628円
ISBN978-4-297-13000-8
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現!
いまはじめるFlutter
iOS/
作って学ぶWeb3
ブロックチェーン、


