murawaki の雑記

はてなグループから移転してきました

Perl で dynamic_use

Perl で module をロードするときには、普通 use を使う。use は

BEGIN { require Module; Module->import( LIST ); }

と等価である。つまり、コードのどこに書いても compile 時に実行される。たとえ if の内側に書いていようが関係なく。

普段は use のこの振る舞いに不満はないが、不便に感じる場合がある。例えば、同じ振る舞いをする module が複数あって、スクリプトの起動オプションによって使う module を変える場合。*1use で記述すると、使わない module までロードされる。もちろん、普段は富豪的にプログラムを書いているから余計な module をロードしても気にしない。でも、開発環境と違う環境で実行したときに問題が発生。使ってもいない module をインストールしてないからって怒られたくない。

代替案。use の代わりに dynamic_use というサブルーチンを用意する。基本的な方法は、とあるメーリングリストで紹介されている。もう少しきちんとしたコードが、やはりメーリングリストで提示されている。少々複雑になっているが、要するに use と同じく require と import をやっているだけ。

しかし、2番目のコードは、ロードしそこなったり、変なものをロードしても死なないようになっている。むしろそっちが本来の目的みたい。私の場合は、ロードしたくてロードしたコードに問題があればちゃんと死んでほしいので、ちょっと手直ししたものを使っている。

他には CPANModule::Optional がある。この module は、存在しない module の代わりに dummy を作る。今のところ、そこまでする必要を私は感じない。

*1:Factory pattern を使うような場合。