这是一个场景,我有两个文件: 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很新。请帮忙!!
答案 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.t
从dir/
运行它,对吗?
如果是这样,那么它正在做正确的事情。由于a.t
位于dir/new_dir
,因此您应始终从FindBin获取dir/new_dir
- 其工作是查找 Bin ary(程序) ),不要找到它被调用的文件,因此A.pm
中的结果与a.t
中的结果相同。
->again
函数用于在同一个perl解释器中运行完全不同的程序的实例,例如mod_perl
所执行的操作,而不仅仅是在单个程序中使用不同的模块。