概要
動的な use lib 実装のためのテスト兼サンプルコード
参考URL:
http://d.hatena.ne.jp/Eitel/20080416/p1
ポイント
- 基本的には use lib の行で動的解釈が発生するようにすれば良い
- eval とか stringification とか
- どうしてもパッケージグローバルな変数か関数が必要になる
- 設定とか無名関数リファレンスとか
いくつかやり方が考えられるが、最終的には好み。
現実問題としてはFindBin
とか使った方が楽。→ "@INC にみる Perl のやりかたがいっぱい - JPerl Advent Calendar 2010 Casual Track"
テストコード
ホストによって use lib するパスを変えるテスト
方法 - stringification
原理は参考 URL と同じ。
use strict;
use warnings;
use Data::Dumper;
use Sys::Hostname;
our %LIB_PATH;
BEGIN
{
%LIB_PATH = ( 'my_pc' => '/Users/hoge/example.com.git/lib'
,'dev.local' => '/var/www/cgi-bin/lib'
,'example.com' => '/usr/local/apache/cgi-bin/lib' );
}
use lib qq($LIB_PATH{hostname()}); # qq によって eval 的な stringification を発生させる
use MyModule; # 動的 use lib で失敗していればここでコケてくれる
print Dumper({'MyModule' => \%MyModule::}); # 試しにスコープをダンプ
方法 - 無名関数リファレンス&クロージャで動的解釈を発生させる
# 〜〜略〜〜
our $LIB_PATH;
BEGIN
{
my %libPath = ( 'my_pc' => '/Users/hoge/example.com.git/lib'
,'dev.local' => '/var/www/cgi-bin/lib'
,'example.com' => '/usr/local/apache/cgi-bin/lib' );
$LIB_PATH = sub
{
return $libPath{hostname()};
}
}
use lib $LIB_PATH->();
# 〜〜略〜〜
設定用のハッシュ定義を関数リファレンスの中に書くか外に書いてクロージャに格納するかは好み次第。
方法 - 無名関数じゃない sub はブロック内でもグローバルでござる
# 〜〜略〜〜
BEGIN
{
my %libPath = ( 'my_pc' => '/Users/hoge/example.com.git/lib'
,'dev.local' => '/var/www/cgi-bin/lib'
,'example.com' => '/usr/local/apache/cgi-bin/lib' );
sub _GET_LIB_PATH
{
return $libPath{hostname()};
}
}
use lib _GET_LIB_PATH();
# 〜〜略〜〜
通常use
が解釈されるタイミングでは関数呼び出しは出来ないが、BEGIN 内で関数を定義する事によって呼び出せるようになる。
一見、パッケージグローバルなスコープを汚していないように見えるが、この_GET_LIB_PATH
はパッケージグローバルな関数になるので注意。