web-dev-qa-db-ja.com

相対ロケーションからPerlモジュールを使用するにはどうすればよいですか?

fooというディレクトリがあり、その中にlibbinがあります。 binのスクリプトにはlibのものが必要です。私はこのようなことをします:

#!Perl
use strict;
use warnings;
use lib '../lib';
use Foo; # <-- comes from lib

しかし、それはスクリプトを実行するためにbin dirにいる必要があることを意味します。きっともっと良い方法があります。これを行う正しい方法は何ですか?

37
Frew Schmidt

標準の FindBin モジュールはあなたが望むことをします。

use FindBin;
use lib "$FindBin::Bin/../lib";

perldoc FindBin 多くのための。

49
Michael Cramer

.plを介して__FILE__への完全なパスを解析し、最後に../libを追加するか、split(/\//,__FILE__)の最後の要素をポップして、/libを追加します。

5
Trey

私は通常、この手法を使用します。悲しいことに、私のPHP日:

特定のファイルwillが現在のファイルに対して相対的であることがわかっており、呼び出し時に呼び出されるエントリポイントまたは周囲の環境がわからない場合に便利です。

しかし、私は通常、この手法を使用しますのみ物事をエミュレートするためにダミーライブラリを必要とするテストスクリプト。

use File::Basename ();
use Cwd            ();
my $base_dir;
my $relative_path; 
BEGIN {
    $realitive_path = '../../' # Path to base of project relative to the current file
    $base_dir = Cwd::realpath( File::Basename::dirname(__FILE__) .'/' . $relative_path );
}


use lib "${base_dir}/lib";
use Foo;

理想的には、これを行うモジュールがどこかにあるはずです。そうでない場合、私は半分書きたくなります。

use Some::Module ();
use lib Some::Module::relative_self('../../lib', __FILE__ ); 
3
Kent Fredric

「FindBin」モジュールは、Perlスクリプトが存在するディレクトリがシステムのPATHにある場合にのみ機能します。それ以外の場合は失敗します。それを克服するために$0値を操作して、Perlモジュールへのパス情報を取得し、その値をuse libに渡すことができます。

このようなもの -

BEGIN {
    use File::Spec::Functions qw(rel2abs);
    use File::Basename qw(dirname);

    #Covert the script path to absolute and get its directory name
    our $path = dirname( rel2abs($0) );

    #Replace the bin tag with lib to get module directory
    $path =~ s{bin/?$}{lib};
}

use lib $path;

EDIT:FindBinモジュールは完全に機能し、 Michaelの回答 で説明されているように使用できます。その動作についての私の理解は不完全だったので、今は撤回する最初のコメントをするようになりました。とにかく、FindBin(TMTOWTDI)を使用して達成できるよりも数行多いにもかかわらず、このメソッドが機能しない理由はわかりません。

3
aks
use lib './';

私の場合、LinuxボックスでPerl v5.14.2を使用して、スクリプトと同じディレクトリにファイルを含めています。

おそらく、スクリプトの作業ディレクトリの下にlibディレクトリとbinディレクトリを移動し、それらを使用してそれらを参照しようとすることがうまくいくでしょう。

use lib './bin/';
1
firetiger77

この答えのコレクションに自分の2セントを追加するために、私は通常、次のように何かを使用してこの問題を解決します。

use lib do {
    use Cwd 'realpath';
    my ($dir) = __FILE__ =~ m{^(.*)/};  # $dir = path of current file
    realpath("$dir/../lib");            # path of '../lib' relative to $dir
};

doブロックを使用するのが好きです。必要なものがすべてきちんと含まれているからです。コピー/貼り付けする必要がある場合、または後でコードを理解する必要がある場合は、個別のBEGINブロックなどを探す必要はありません。

上記のコードは単純に/は、dir/filenameセパレーターとして使用されます。

0
zrajm

私の解決策:

use lib substr(__FILE__, 0, rindex (__FILE__, "/"));
0
Leo