要回答这个问题,您可以使用 Module::Path 来检查分发中的任何模块文件是否在blib/lib
目录中。这不是万无一失的,因为有人可能prove
在另一个名为 的目录内的发行版上运行blib
,但我认为这不太可能。这也有一个缺点,即要求发行版.pm
在某处有一个文件,但情况可能并非如此。
或者,您可以检查保存该目录的t
目录(在测试脚本中,这将$Bin
来自FindBin
)中是否有blib
目录。但是,如果您在make
没有运行make clean
该脚本后又进一步开发了该脚本,则当您运行prove
该blib
目录中的陈旧脚本时,仍将运行该脚本。
在我对我的问题的评论中,我提到了检查$INC{'blib.pm'}
。这仅在使用 调用测试脚本时才有效-Mblib
,并且make test
不这样做。相反,它ExtUtils::Command::MM::test_harness
使用blib/lib
和blib/arch
作为包含目录调用。
Once you know that you're running code out of blib, then you need to change both the include path, which should be blib/lib
, and the script path, which should be blib/script/whatever
(and no .pl
if your script had one originally, because make
removes it). So here's a correct version of the original example:
use Module::Path 'module_path';
use Path::Tiny;
use FindBin;
use Test::More;
plan tests => 1;
use Capture::Tiny;
my $module_path = path(module_path('My::Thing'));
my $HAS_BLIB =
$module_path #Thing.pm
->parent #My
->parent #lib
->parent #blib
->basename eq 'blib';
my $script_path = $HAS_BLIB && path(qw(blib script my_script)) ||
path(path($FindBin::Bin)->parent, 'bin', 'my_script.pl');
my $include = $HAS_BLIB && '-Mblib' || # could also do -Iblib/lib -Iblib/arch
'-I'. path(path($FindBin::Bin)->parent, 'lib'); # would use installed version of C code
my @command = ($^X, $include, $script_path, @batch_files);
my ($stdout, $stderr) = capture {system(@command)};
is($stderr, '', 'no errors reported from script');
#more tests here
This is an awful lot of trouble, and in this case I don't think that it's necessary. I'm not entirely sure when it would be useful. If your distribution has C/C++ code then you might want to always use the blib solution, which adds blib/arch to the include path. With the above simple example, the test passes using the non-blib settings because the original files are still available. Little change happens to the files copied into the blib
directory. So when I was debugging this, the only way I could tell if it was doing the right thing was to print out the full command used!
In other words, it wasn't very testable, and if someone really needs this then they should create a module to manage it (and test that). Test::Script seems to always use -Mblib, which would mean you could be using a stale make
result, and you have to pass in the path of the script, meaning it's up to you to decide to whether to use the original script or the one inside blib/script
.