使っちゃいけない標準モジュール

2010-12-23

gfxと申します。
Perlは後方互換性を重視しているので、標準モジュールはめったに取り除かれる事がありません。しかしそれでも、いくつかのモジュールが将来的に取り除かれる見込みです。そのようなモジュールは使用しないほうがいいでしょう。また、取り除かれはしないものの、様々な理由から使用すべきでないモジュールもいくつかあります。今日は、そういった使うべきでないモジュールを紹介します。なお、このエントリの対象バージョンは5.8から5.14を想定しています。

さて、まずは取り除かれるモジュールです。現在のところ、以下の三つのモジュールが5.14でコアから削除される予定です。

Class::ISAはクラス階層を直列化するモジュールですが、5.10以降はmroに取って代わられました。5.10未満のバージョン用にはMRO::Compatが用意されているため、こちらを使ってください。
Pod::Plainerは現行スタイルのPODを旧スタイルのPODに変換するモジュールです*1。旧スタイルのPODしか理解できないPOD処理ルーチンのためのものなのでしょうが、いまや必要ありません。このモジュールの事は忘れてください。
Switchはスイッチ文を導入するためのソースフィルタモジュールです。5.10以降はスイッチ文が組み込みになったため、このモジュールは不要になりました。それだけでなく、このモジュールはソースコードを書き換えるため、しばしば不可解な現象を引き起こします。たとえばmstは以下のエントリでそのような現象を報告しています。

このモジュールを避けると5.10未満ではスイッチ文がつかえない事になりますが、余計な事で時間を取られたくないなら使用しない方がいいでしょう。

次に、使うべきでないモジュールです。これらを使っていたからといって必ずしも問題がおきるとは限りませんが、新しいコードでは避けた方がいいでしょう。いくつかのモジュールは実際に警告を発生させることがあります。

UNIVERSALは、UNIVERSAL::isa()とUNIVERSAL::can()をエクスポートするモジュールです。しかし、この二つのメソッドを関数として呼び出すのは誤りです。blessed($x) && $x->isa(...)などを使ってください。Perl 5.12ではこの二つのメソッドをインポートしようとすると警告が出ます。このモジュールはドキュメントとして存在し続けるでしょうが、useする必要はありません。
Shellは外部コマンドを関数のように呼び出せるようにするモジュールです。5.12からはuseすると警告されるようになりました。このモジュールはもともとAUTOLOADのデモとして作成されたものなので、特に使う必要はないでしょう。
FileHandleはファイルハンドルを値として使用するためのモジュールでしたが、いまや単なるIO::Fileのラッパーなので、ロードしてもメモリを余計に消費するだけです。単なるラッパーになってすでに10年以上経過しているので、新しいコードで使用する必要はまったくありません。また、5.6から無名ファイルハンドルを生成することができるようになったため、IO::Fileを使う必要性も減少しています。
DynaLoaderはXSモジュール用の.so/.dllをロードするためのモジュールです。いまはXSLoaderがあるのでこちらを使いましょう。DynaLoaderはベースクラスに指定することによって機能を提供するので、余計なメソッドをいくつか継承してしまいます。また、モジュール自体もXSLoaderのほうが軽量です。
baseは@ISAを設定するプラグマモジュールです。代わりに5.10から標準になったparentを使いましょう。baseを使っていると思わぬ罠にハマることがありますが*2、parentではそのようなことはありません。
bytesはsubstr()などの挙動を強制的にバイト単位にするプラグマモジュールです。このプラグマの元で文字列操作を行うと、テキスト文字列*3を渡してもバイト列を渡しても同じ挙動になりますが、そのような挙動はおそらく間違っています。テキスト文字列を渡すべきかバイト列を渡すべきかというのはそのルーチンの仕様の問題であり、そのルーチンがバイト列を処理するルーチンであるならば、使用者がきちんとバイト列を渡すべきです。perlunifaq (日本語訳)も参考になります。

いじょ。JPerl Advent Calendar随一の後ろ向きなエントリを目指しました!
いよいよ明日はクリスマスイブですね!Perl界のトリックスターが満を持して登場します!お楽しみに!

*1: C<< .. >>といった書き方は、初期のPODには存在しなかったようです。
*2: ベースモジュールのロードに失敗したことを検出できない、誤ってロード済みと判断してロードしないなどの問題が確認されています。
*3: 「テキスト文字列」は昔はutf8-flagged文字列やユニコード文字列と呼ばれることがありましたが、それは誤りです。utf8 flagの立っていない、Latin-1(ISO-8859-1)でエンコードされた文字列もまた正しいテキスト文字列だからです。