問題の歴史:
Perlは、モジュールのサポートが登場して以来、動的および静的なコードのロードをサポートしています。これを実現するために、言語は3つの異なるメカニズム:require、use、およびdoを提供しています。それぞれ特有の特徴があり、異なる実行ライフサイクルとプログラムの動作コンテキストへの影響があります。
問題:
ロードメカニズムの誤った選択や、それらの違いの理解不足は、しばしばバグを引き起こします:モジュールの再度のロード、スコープの問題、実行時エラー(例えば、失敗したロード、未初期化の変数や関数など)。
解決策:
use — コンパイル時にモジュールを読み込みます。定義されている場合は、自動的にimportメソッドを呼び出します。プログラムの開始時にモジュールや宣言を読み込むために使用されます。require — 実行時にファイルまたはモジュールを読み込み、プログラム中に一度だけ行われます。条件に基づいてファイルを動的にロードするのに適しています。do — Perlコードとしてファイルを単に実行し、呼び出しごとに毎回実行されます。特別なケース(例えば、設定ファイル)のために使用されることは稀です。コードの例:
use Some::Module; # 静的ロード if ($config{plugin}) { require "$config{plugin}.pm"; # 動的ロード } do 'local_config.pl'; # 毎回呼び出すたびに実行
主な特徴:
useはpackage/moduleとのみ連携し、importを呼び出し、コンパイル時に発生します。requireはファイルとモジュールとの連携を行い、実行時に発生します。doはモジュールをキャッシュせず、ファイルの内容を単に実行します。requireを使用して変数とSome::Moduleタイプのモジュールを関連付けることはできますか?
できますが、ファイルまでのパスを明示的に指定する必要があるか、モジュール名をパスに変換する必要があります:
my $mod = 'Some::Module'; $mod =~ s!::!/!g; require "$mod.pm"; # 正しい
もしdoがファイルを見つけられなかった場合、どうなりますか?
doはfalse (undef) を返し、$@にエラーを記録します — use/requireのようにパニックを引き起こすことはありません。
同じファイルに対してrequireを二度呼び出したらどうなりますか?
requireはファイルを初回のみロードし、以降の呼び出しでは再度ロードしません。たとえ元のファイルが変更された場合でもです。
プロジェクトでは、doを使用してプラグインを動的に読み込もうとし、返り値を確認せず、requireと混同しました。
利点:
欠点:
条件に基づいてrequireを使用し、常にモジュール名をパスに変換しました。ロード試行後に$@を確認しました。
利点:
欠点: