在多个模块中使用FindBin

时间:2011-10-07 09:48:10

标签: perl

这是一个场景,我有两个文件: dir / A.pm 2. dir / new_dir / a.t

这是A.pm的样子:

package A;
use FindBin;
use Test::More;
is (FindBin->again, 'dir', 'got dir');
1;                    

这就是a.t的样子:

use FindBin;
use Test::More qw(no_plan); 
use A;
is (FindBin->again, 'dir/new_dir', 'got dir/new_dir');

所以我用perl new_dir / a.t运行文件a.t并期望我的测试通过。但这是我的测试结果:

not ok 1 - got dir
#   Failed test 'got fir'
#   at A.pm line 6.
#          got: 'dir/new_dir'
#     expected: 'dir'
ok 2 - got dir/new_dir
1..2

我做错了吗?我对perl很新。请帮忙!!

3 个答案:

答案 0 :(得分:7)

作为Dave Sherohman notes,FindBin用于查找主脚本的位置,而不是单个模块。来自文档:

NAME
       FindBin - Locate directory of original perl script

(不可否认,文档确实有些令人困惑地引用了“已知问题”部分中的“模块”,但它并不代表您认为它的含义。)

无论如何,如果您使用perldoc -m FindBin查看来源,您会看到FindBin从$0变量获取脚本的路径。如果您有兴趣通过use(或require)找到所包含模块的位置,则应该在%INC下查找,如下所示:

package Foo::Bar;
use File::Spec;
my ($vol, $dir, $file) = File::Spec->splitpath( $INC{'Foo/Bar.pm'} );

答案 1 :(得分:5)

FindBin找到Perl启动文件的位置,而不是当前正在执行的文件的位置。

我不明白为什么你需要模块的路径 - File::ShareDir可以用来访问模块的数据文件 - 但是下面会找到它:

use Cwd            qw( realpath );
use File::Basename qw( dirname );

my $module_dir = dirname(realpath(__FILE__));

与Find :: Bin相同的警告:只有在chdir未被更改时才有效。

答案 2 :(得分:3)

如果我正确理解了这个问题,a.t位于dir/new_dir/目录中,您正在使用new_dir/a.tdir/运行它,对吗?

如果是这样,那么它正在做正确的事情。由于a.t位于dir/new_dir,因此您应始终从FindBin获取dir/new_dir - 其工作是查找 Bin ary(程序) ),不要找到它被调用的文件,因此A.pm中的结果与a.t中的结果相同。

->again函数用于在同一个perl解释器中运行完全不同的程序的实例,例如mod_perl所执行的操作,而不仅仅是在单个程序中使用不同的模块。