在多个模块中使用FindBin

jun*_*bon 5 perl

这是场景,我有两个文件:1.dir/A.pm 2. dir/new_dir/at

这是A.pm的样子:

package A;
use FindBin;
use Test::More;
is (FindBin->again, 'dir', 'got dir');
1;                    
Run Code Online (Sandbox Code Playgroud)

这是看起来像:

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

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

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
Run Code Online (Sandbox Code Playgroud)

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

Ilm*_*nen 7

正如Dave Sherohman所说,FindBin用于查找主脚本的位置,而不是单个模块.从文档:

NAME
       FindBin - Locate directory of original perl script
Run Code Online (Sandbox Code Playgroud)

(不可否认,文档有点令人困惑地引用了"已知问题"部分中的"模块",但它并不意味着您认为它意味着什么.)

无论如何,如果你查看源代码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'} );
Run Code Online (Sandbox Code Playgroud)


ike*_*ami 5

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

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

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

my $module_dir = dirname(realpath(__FILE__));
Run Code Online (Sandbox Code Playgroud)

与Find :: Bin相同的警告适用:这仅chdir在未更改时有效.