开发者

Using FindBin in more than one module

开发者 https://www.devze.com 2023-04-11 15:28 出处:网络
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;

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号