※このエントリは Perl Advent Calendar 2016 の15日目のエントリです。
どーも、わいとんです。
早速ですが、みなさんはPerlのライブラリパスをどんな風に指定していますか?
そもそもスクリプト内で指定してない?絶対パスで直接指定?それともFindBin
を使ってる?
今回はわいとんがよくやっているFile::Spec
とFile::Basename
を使ったライブラリパス指定の方法を紹介します。
例
以下のようなプロジェクトがあったとします。
1 | ./ |
cpanfile
は以下のような内容です。
1 | requires 'perl', '5.008001'; |
これをcpm install
なんてやった場合、local/lib/perl5
配下に依存ライブラリがどんどん入ってきます。(cpmについてはskajiさんのエントリを参照してください。)
で、bin/run.pl
からMyProj::Client->new(...);
なんてやりたいなぁって思った時に、以下のように書くと思います。
1 | use strict; |
でもって、実行時に
1 | perl -Ilib -Ilocal/lib/perl5 ./bin/run.pl |
なぁんて書くと思います。別に悪くないけど、面倒ですよね。
ちょっと賢くFindBinを使う
で、use lib
とFindBinを組み合わせて、以下のようにしたりしますよね。(しますよね?したことありません?)
1 | use strict; |
実行時にはこんな感じで。
1 | perl ./bin/run.pl |
楽になりましたね!でもでもでもでもチョッッット待ってwww それってカレントディレクトリがプロジェクトフォルダの直下にないと動かなくないっすか?(動かないですよね?)あとそれWindowsじゃ動かなくないですか?(Windowsなんか使わない?あ、すみませんww)
File::SpecとFile::BasenameとFILEを使う
まあそこで出てくるのがFile::SpecとFile::Basenameなんですね。
超雑に解説すると、File::Spec
ってのはOS間で異なるパス表現(¥
とか/
とかそういうやつ)を吸収してくれるライブラリで、File::Basename
てのは、食わせた文字列をパス表現文字列とみなしてざっくりパーズし、フォルダまでのパスとかファイル名とかをよしなに引っ張ってきてくれるライブラリです。
あと__FILE__
っていうのは実は組みこみ関数でして、__FILE__
が記述されているファイルのパス(つまり実行されるスクリプトのパスそのもの)を返してくれます。
んで、こいつらを使ってさっきのbin/run.pl
を書き換えると、こんな感じになります。
1 | use strict; |
若干冗長ですが、実行時は常にスクリプトを正しく指定するだけでOK。
1 | perl ./bin/run.pl |
例えばlib/MyProj/
からでも
1 | perl ../../bin/run.pl |
と実行できます。
少し補足。 File::Spec->catdir(...)
は、引数にリストを食わせることで、実行環境に応じたパス文字列を仕立て上げてくれます。dirname(...)
は与えられたパス文字列のディレクトリパスを返してくれます。
これらを組み合わせて、どの環境でどのパスから実行されても、読み取りたいライブラリパスがずれずに利用可能となる、と。こういうわけです。
何より、File::Spec
もFile::Basename
もコアモジュールなので、Perl5が入っていればまず使えないってことはないんじゃないでしょうか。→ツッコミ参照ください
まとめ
- ライブラリパスをがっちりつかんで離さないスクリプトを書くための方法を紹介しました。
File::Spec
とFile::Basename
を使うぞって言いながら__FILE__
も使いました。- きっとWindowsの人もニッコリ。
cpm
かわいいよcpm
ツッコミもらいました
@ytnobody local/lib/perl5にFile::Specが入っていてuse libの段階ではFile::Spec使えないことがありました…
— Shoichi Kaji (@shoichikaji) December 16, 2016
@ytnobody ちょっと前のPath::TinyがFile::Spec 3.40をrequireしていたので結構起きてました。https://t.co/C7rGuQD215
— Shoichi Kaji (@shoichikaji) December 16, 2016
だそうです。。。skajiさん、ありがとうございますm(_ _)m