I have a dir called foo
, and in that I have lib
and bin
. The scripts in bin
need stuff in lib
. I do someth
The "FindBin" module will only work if the directory that the perl script resides in is in your system PATH, else it will fail. To overcome that you can manipulate the $0
value to get your path-to-perl-module information and pass the value to use lib
.
Something like this -
BEGIN {
use File::Spec::Functions qw(rel2abs);
use File::Basename qw(dirname);
#Covert the script path to absolute and get its directory name
our $path = dirname( rel2abs($0) );
#Replace the bin tag with lib to get module directory
$path =~ s{bin/?$}{lib};
}
use lib $path;
EDIT: The FindBin module works just perfectly and can be used as described in Michael's answer. My understanding of its workings was incomplete and so led me to making the first comment which I now retract. Anyway, I don't see any reason why this method shouldn't work albeit with a few more lines than could be achieved using FindBin (TMTOWTDI).
I generally use this technique. Its sadly inspired from my PHP days:
Its handy in situations where you know where a given file will be relative to the current one, and aren't sure of the entry points it may be called in or the surrounding environment at calltime.
However, I would generally use this technique only for test scripts which need dummy libraries for emulating things.
use File::Basename ();
use Cwd ();
my $base_dir;
my $relative_path;
BEGIN {
$realitive_path = '../../' # Path to base of project relative to the current file
$base_dir = Cwd::realpath( File::Basename::dirname(__FILE__) .'/' . $relative_path );
}
use lib "${base_dir}/lib";
use Foo;
Ideally there should be some module somewhere that does this, if not, I'm half tempted to write one:
use Some::Module ();
use lib Some::Module::relative_self('../../lib', __FILE__ );
My solution:
use lib substr(__FILE__, 0, rindex (__FILE__, "/"));
Just to add my own two cents to this collection of answers, I usually solve this problem using something along these lines:
use lib do {
use Cwd 'realpath';
my ($dir) = __FILE__ =~ m{^(.*)/}; # $dir = path of current file
realpath("$dir/../lib"); # path of '../lib' relative to $dir
};
I like using a do
block because everything needed is so neatly contained therein. If you ever need to copy/paste, or try to understand your code at a later time you don't have to look for a separate BEGIN
block or anything like that.
The above code naïvely assumes that /
is used as a dir/filename separator.
How about:
BEGIN: {
push @INC, '/full/path/to/lib';
}
To do a relative reference would assume that you're going to keep it in the bin dir, so insert the relative reference there instead.
Parse out the complete path to your .pl
via __FILE__
and and tack the ../lib
on the end or pop off the last element of split(/\//,__FILE__)
and add /lib
to that.