モダンPerlの世界へようこそ

第18回 local::lib:ふだんと違う環境でPerlを使う

この記事を読むのに必要な時間:およそ 4 分

いつでも理想の環境を使えるとは限りません

「弘法筆を択ばず」ということわざもありますが,なんであれ手になじむまで使い込んだ道具を持っている人は,環境が変わってその道具が使えなくなるとやはりいらいらするものです。

Perlの場合もそう。日頃から自分の必要や興味に応じてがんがんCPANモジュールをインストールしていると,何らかの事情でまっさらに近いPerlを使わなければならなくなったとき,途方に暮れます。本来のコードを書き始める前に,モジュールのインストールだけで一日潰してしまった経験をお持ちの方も少なくないことでしょう。

今回は,そんな「ふだんと違う」環境でもなるべくストレスなくPerlを使えるようにするためのモダンな努力をいくつか紹介してみます。

PERL5LIBという環境変数を活用する

Perlはディストリビューションに同梱されているコアモジュールを保護するために,CPANからインストールするモジュールをコアモジュールとは別の場所(典型的にはsite/lib以下)に配置できるようになっています。このようにしておくことで,あとからsite/lib以下にインストールしたモジュールが何らかの理由で壊れても,もともとlib以下にインストールしてあったコアモジュールがバックアップの役割を果たせる,というのがそのねらいです。

同様に,Perlにはインストール済みのモジュールを保護するために,-IというスイッチやPERL5LIBという環境変数を利用してモジュールを読み込むパスを変更する仕組みがあります。これを使えば,(明示的にlibプラグマを追加するなどして)アプリケーションやインストール済みのモジュールを改変しなくても,特定の環境でのみ必要なモジュールを使うようにできます。

たとえば,/home/foo/myapp以下に5.7系列のMooseに対応していない)Catalystで開発したアプリケーションがあるとしましょう。これがCatalyst 5.8系列でも正しく動作するか確認したいとき,いきなりCPANでCatalystのバージョンアップをするのはやや乱暴なやり方です。このような場合はひとまず/home/foo/catalyst58以下にCatalyst 5.8系列の最新版をリポジトリからチェックアウトするなりtarballをダウンロード・展開するなりして,PERL5LIBに/home/foo/catalyst58/libをセットしてから,myappのテストを実行したり,開発用サーバを起動するのが常套手段。こうすればほかのアプリケーションにはまったく影響を与えず,もともとのコードにもいっさい手を加えずに,新しいモジュールを使ったテストを実行できます。 PERL5LIBに複数のパスを登録したい場合は,Unix系のOSならふつう「:」,Windowsの場合は「;」で区切ります※1)。また,コンパイルする必要があるモジュールの場合は,単にlibを追加するのではなく,コンパイル後にできるblib以下の各ディレクトリを(/home/foo/catalyst58/blib/lib:/home/foo/catalyst58/blib/archのように)登録します。

もっとも,この例のように外部のモジュールが少ない場合はともかく,大きなアプリケーションの移行テストをするときにPERL5LIBに何十個もパスを列挙するのは現実的ではありません。そのような場合は,どこか(ふだんモジュールをインストールしている場所とは異なる)特定のパスに複数のモジュールをインストールしておいて,そのパスをPERL5LIBに登録する方が簡単です。

たとえば,先ほどの/home/foo/myapp以下のアプリケーションを,Catalyst 5.8だけでなく,MooseやClass::MOPの開発版も入れた状態でテストしたいとしましょう。もちろんPERL5LIBに/home/foo/catalyst58/lib,/home/foo/moose/lib,/home/foo/class-mop/blib/lib,/home/foo/class-mop/blib/archという4つのバスを登録してもよいのですが(Class::MOPはコンパイルが必要なモジュールなので,/home/foo/class-mop/libではなくblib以下のディレクトリを登録する必要があります),それよりは,少しだけ手間はかかりますが,Catalyst 5.8やMooseのディレクトリでもmakeを実行しておいて,/home/foo/catalyst58/blib,/home/foo/moose/blib,/home/foo/class-mop/blibの中身をすべて/home/foo/extlibs以下にコピーし,PERL5LIBには/home/foo/extlibs/libと/home/foo/extlibs/archのみ指定するようにしたほうが便利です。

※1

正しい区切り記号を知りたい場合はこのようなワンライナーを実行してください。

perl -MConfig -e 'print $Config{path_sep}'

旧来の設定の保存の仕方

とはいえ,外部ファイルを更新するたびにいちいちお決まりのコピー先を指定してコピーするのは面倒な話ですし,Perl的ではありません。このような作業はもちろんもっと簡単にできるようになっています。

たとえば,Makefile.PLがExtUtils::MakeMaker(や,それを裏で使っているModule::Installを使って書かれている場合,「perl Makefile.PL」を実行するときにこのようなオプションを与えておくと,わざわざ自分でblibディレクトリ以下をコピーしなくても,いつものようにmake installすれば指定したディレクトリにインストールできるようになります。

> perl Makefile.PL PREFIX=/home/foo/extlibs
> make
> make install  # /home/foo/extlibs以下にインストール

ExtUtils::MakeMakerが十分新しければ,PREFIXのかわりにINSTALL_BASEなどのオプションを与えることもできます(こちらのほうがパスがより直感的なものになります)。また,これらのオプションはPERL_MM_OPTという環境変数に保存しておくこともできます。この環境変数が定義されていると,直接perl Makefile.PLを実行したときだけでなく,CPANシェルなどからインストールする場合も指定したディレクトリにモジュールをインストールできるようになります(詳細はExtUtils::MakeMakerのPODをご覧ください)。

Module::Buildを使っているモジュールの場合は,インストール時に--install_baseなどのオプションを指定することで同じような処理を行うことができます。

> perl Build.PL
> ./Build
> ./Build install --install_base /home/foo/extlibs

また,MODULEBUILDRCという環境変数を利用すると,Module::Build用のオプションをファイルに保存しておくことができます(こちらも詳細はModule::BuildのPODをご覧ください。なお,Module::Buildの次のバージョンではExtUtils::MakeMakerのようにPERL_MB_OPTという環境変数もサポートされることになっています)。

これらのオプションは,環境変数だけでなく,CPANCPANPLUS(一時的ないし恒久的な)設定として保存することもできます。はじめてCPANシェルを起動したときにこのようなメッセージが出ていたのを覚えている方もいることでしょう。これや,これに続く関連した設定を切り替えることで,いちいち環境変数を設定しなくても,実験的なモジュールだけ別の場所に仮インストールすることができるようになります。

Every Makefile.PL is run by perl in a separate process. Likewise we
run 'make' and 'make install' in separate processes. If you have
any parameters (e.g. PREFIX, UNINST or the like) you want to
pass to the calls, please specify them here.

If you don't understand this question, just press ENTER.

Typical frequently used settings:

    PREFIX=~/perl    # non-root users (please see manual for more hints)

 
Parameters for the 'perl Makefile.PL' command? [INSTALLDIRS=site]

著者プロフィール

石垣憲一(いしがきけんいち)

あるときは翻訳家。あるときはPerlプログラマ。先日『カクテルホントのうんちく話』(柴田書店)を上梓。最新刊は『ガリア戦記』(平凡社ライブラリー)。

URLhttp://d.hatena.ne.jp/charsbar/

コメント

  • .

    lib プラグマでも同じことができますよ

    Commented : #1  らくだのり (2012/04/22, 19:03)

コメントの記入