2011-10-07 91 views
5

这里使用FindBin是该方案,我有两个文件: 1. DIR/A.pm 2. DIR/NEW_DIR /在在多个模块

这是A.pm的样子:

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

这是怎样的样子:

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

于是我就在文件中使用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 

我做错了什么?我对perl很陌生。请帮忙!!

回答

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'}); 
+0

“无可否认,文档中有些混淆地提到”已知问题“一节中的”模块“,但这并不意味着您认为它的意思。” - 我想我误解了FindBin->的含义。我现在很清楚。感谢所有的帮助! – junbon

3

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

如果是这样,那么它正在做正确的事情。由于a.tdir/new_dir,应始终从FindBin得到dir/new_dir - 它的工作是查找元(程序),没有发现它正在从所谓的文件,这样的结果将是相同的A.pm作为它在a.t

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

5

FindBin发现的Perl推出了文件的位置,而不是正在执行的文件。

我不明白为什么你需要的路径模块— File::ShareDir可用于访问模块的数据文件—但下面会发现:

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

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

同样的警告作为查找:: Bin适用:仅在chdir尚未更改时适用。

+0

太棒了!感谢提到File :: ShareDir,不知道这一点。 –