自作pmをuse libする
下にlibとかつくってそこにおいた自作pmをuseするとき、相対パスで呼び出してしまうと実行ディレクトリが違う場合(cronでまわしたりとか)に都合が悪かったりします。
そこで、以下のようにBEGINブロック内でスクリプト自身のパスをとってきてからuse libとかしてるんですが、このやり方おかしかったりしないんだろうか。もし、もっとこうした方がいいとかあればぜひお教え下さい。
├ main.pl ├ lib └ Hoge └ Foo.pm
#!/usr/bin/perl use strict; use warnings; use File::Basename; my $w_dir; BEGIN { $w_dir = dirname $ENV{_} } use lib "$w_dir/lib"; use Hoge::Foo; my $foo = Hoge::Foo->new("tester001"); print $foo->name;
package Hoge::Foo; sub new { my $class = shift; my $name = shift; bless { name => $name } , $class; } sub name { my $self = shift; return $self->{name}; } 1;
追記(同日):
一部、記述を追加しました。
追記(3/7):
上記のようなことをやりたいんなら「$ENV{_}なんてものを使うより単に$0でいいじゃん」というのが自然な気がしてます。cronでまわすにしてもそれでできるわけだし。
use File::Basename; my $w_dir; BEGIN { $w_dir = dirname $0 }
みたいな感じで。
以下、コメントで教えていただいたものも紹介させていただきます。
use File::Basename; use File::Spec; my $w_dir; BEGIN { $w_dir = dirname(File::Spec->rel2abs($0)); }
上記と同じような感じですが、常にフルパスを取得できるようにしています。
dirname $0だと./hoge.plで実行すると$w_dirに「.」が入り、/home/user/work/hoge.plで実行すると「/home/usr/work」が入りますが、上記のやり方だと常に「/home/user/work」が取得できますね。
もうひとつはFindBinモジュールを使うやり方。これだとFile::Basenameを使わずにFindBinだけでいけますね。
use FindBin; my $w_dir; BEGIN { $w_dir = $FindBin::Bin; }
追記(3/8):
さらにFindBin::libsを使えばlibを探してきてuse libしてくれます。超便利ですね!
use FindBin::libs;
名前の通り、デフォルトではlibを探しにいきます。他のディレクトリ名を指定すればそこをuse lib。
use FindBin::libs qw{ base=src print };
とやるとuse libしたディレクトリ一覧が以下のように標準出力されます。
Found */src: /home/webmaster/script/src /var/src
お答えいただいた方々、どうもありがとうございました。