Using FindBin in more than one module
Here is the scenario, I have two files: 1. dir/A.pm 2. dir/new_dir/a.t
This is how A.pm looks like:
package A;
use FindBin;
use Test::More;
is (FindBin->again, 'dir', 'got dir');
1;
This is how a.t looks like:
use FindBin;
use Test::More qw(no_plan);
use A;
is (FindBin->again, 'dir/new_dir', 'got dir/new_dir');
So I ran file a.t with perl new_dir/a.t and expect my tests to pass. But this is my test result:
not ok 1 - got dir
# Failed test 'got fir'
# at A.pm line 6.
# got: 'dir/new_dir'
# expected: 'dir'
ok 2 -开发者_如何学JAVA got dir/new_dir
1..2
Am I doing anything wrong? I am very new to perl. Please help!!
As Dave Sherohman notes, FindBin is for finding the location of the main script, not individual modules. From the documentation:
NAME
FindBin - Locate directory of original perl script
(Admittedly, the documentation does, somewhat confusingly, refer to "modules" in the "KNOWN ISSUES" section, but it doesn't really mean what you think it means by that.)
Anyway, if you look at the source with perldoc -m FindBin
, you'll see that FindBin obtains the path to the script from the $0
variable. If you're interested in finding the location of a module included via use
(or require
), you should look under %INC
instead, something like this:
package Foo::Bar;
use File::Spec;
my ($vol, $dir, $file) = File::Spec->splitpath( $INC{'Foo/Bar.pm'} );
FindBin finds the location of the file Perl launched, not of file currently executing.
I don't see why you'd need the path to a module — File::ShareDir can be used to access your module's data files — but the following will find it:
use Cwd qw( realpath );
use File::Basename qw( dirname );
my $module_dir = dirname(realpath(__FILE__));
The same caveat as Find::Bin applies: This only works if chdir
hasn't been changed.
If I understand the question correctly, a.t
is in the directory dir/new_dir/
and you're using new_dir/a.t
to run it from dir/
, right?
If so, then it is doing the right thing. Since a.t
is in dir/new_dir
, you should always get dir/new_dir
from FindBin - its job is to Find the Binary (program), not to find the file it's being called from, so the result will be the same in A.pm
as it is in a.t
.
The ->again
function is for running instances of completely different programs from within the same perl interpreter, such as what mod_perl
does, not for just using different modules within a single program.
精彩评论