本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回のハッカーは普段Perlでスマートフォンゲームのサーバサイドの開発をしているybrliiuこと楠田来安さんで、
本稿に記載しているコードはPerl 5.
Perlにおける動的なモジュールロード
言語の柔軟性や文化的な要因により、
本稿では、
まずは動的なモジュールロードについての説明と、
静的なモジュールロード
モジュールロードする場合、use
を使うと思います。use
を使った場合、use
などコンパイルフェーズで行うモジュールロードのことを静的なモジュールロードと呼びます。
静的にモジュールロードする場合は、
動的なモジュールロード
対して動的なモジュールロードは、
動的にモジュールロードする場合はロードするタイミングやモジュールを自由に決めることができるため、
動的なモジュールロードをする方法
動的なモジュールロードをする方法のうち、
require──モジュールロードをする組込み関数
Perl組込みの関数を利用して動的にモジュールロードする場合、require
関数を利用します。しかし、require
関数にBareword
たとえば次のコードでは、require
は@INC
からFoo::Bar
というファイルを探してロードを試みます。
require
関数にモジュール名としてBareword以外の値を渡したい場合は、require
関数を呼び出している箇所全体をeval
で評価する必要があります。
しかし、eval
でrequire
を評価するコードはできるだけ書きたくありません。
- オーバーヘッドが発生する
- ロード時のエラーが握りつぶされる
- プログラム外部から渡された値を
eval
で直接評価するとインジェクション攻撃が可能になる - 不格好なコードになる
CPANにはeval
をしなくても動的にモジュールロードできるモジュールが存在していますので、require
にBareword以外の値を渡したい場合はそれらのモジュールローダを利用することが推奨されます。
Module::Load──コアモジュールのシンプルなモジュールローダ
Module::LoadはPerl 5.
Class::Load──クラスモジュール向けのモジュールローダ
Class::Loadは、Moose
の裏側などで利用されているクラスモジュール向けのモジュールローダです。ロードするモジュールがすでに内部パッケージやファイル名とパッケージ名が対応していないモジュールによって定義されている場合はファイルを読み込まずエラーにならないので、
次のコードもエラーにならず動作します。
useする場合と挙動が異なる点
動的にモジュールロードした場合、use
で静的にモジュールロードした場合と挙動が異なる点があるので注意が必要です。
importメソッドが呼ばれない
use
した場合、import
メソッドを呼び出しますが、import
メソッドは呼ばれません。ですので、import
メソッドの中で実行されるはずだった処理を行いたい場合は、import
メソッドを呼び出す必要があります。
Module::Load
を利用している場合、autoload
関数を利用するかload
関数に追加の引数を与えると、import
メソッドを呼び出します。
括弧を省略してサブルーチンを呼び出せない
別モジュールからuse
でサブルーチンをインポートした場合は、
しかし、
同様に、
この問題は括弧を省略せず呼び出したり、
あるいは事前にインポートするサブルーチンの宣言を行うことで解決できます。
CHECK、INITコードブロックに書かれたコードが実行されない
CHECK
ブロック、INIT
ブロックは、
<続きの
本誌最新号をチェック!
WEB+DB PRESS Vol.130
2022年8月24日発売
B5判/168ページ
定価1,628円
(本体1,480円+税10%)
ISBN978-4-297-13000-8
- 特集1
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現! - 特集2
いまはじめるFlutter
iOS/Android両対応アプリを開発してみよう - 特集3
作って学ぶWeb3
ブロックチェーン、スマートコントラクト、NFT