nck
nck

Reputation: 2221

How can I add relative paths to libraries in perl?

I want to have a library (my_library_1) which makes use of another library in a folder relative to itself. If I write it like this:

use lib "/./libraries/";
use my_library_2;

It will use the path from where I execute the script.

If I use the following as proposed in other similar quiestions:

use FindBin;
use lib "$FindBin::Bin/./libraries/";
use my_library_2;

It will be relative to the main script being executed, therefore if I'm calling this library from another script, and then this library calles the other one (my_library_1), the library declaration will not be as expected if the first library (my_library_1) and the main script are in the same folder.

How can I solve this issue without relying on absolute paths?

Edit: To add some more information This is the current structure:

folder
\_folder_1
 \__main_script
\_folder_2
 \__my_library_1
 \__folder_1
   \___my_library_2

I want to reference library_3 from library_2 with a relative path. The two proposed options do not work when I use them on "my_library_2".

Upvotes: 0

Views: 84

Answers (2)

Grinnz
Grinnz

Reputation: 9231

lib::relative is a straightforward way to use __FILE__ to add absolutized lib paths relative to either a script or module. It also documents the equivalent core module commands so it doesn't need to be installed.

In the script:

use lib::relative '../folder2';

or:

use Cwd ();
use File::Basename ();
use File::Spec ();
use lib File::Spec->catdir(File::Basename::dirname(Cwd::abs_path __FILE__), '../folder2');

Similarly in the module:

use lib::relative 'folder1';

I recommend the much simpler __FILE__ approach over FindBin in all cases - FindBin is action at a distance, requires workarounds, and has serious bugs on old Perls that cannot be fixed because it isn't available on CPAN.

Upvotes: 1

Håkon Hægland
Håkon Hægland

Reputation: 40748

Here is one approach using __FILE__ to get the directory name of my_library_1.pm:

folder1/main.pl:

use strict;
use warnings;
use FindBin;

use lib "$FindBin::RealBin/../folder2/";
use my_library_1;

folder2/my_library_1.pm:

package my_library_1;
use strict;
use warnings;
use File::Basename qw(dirname);

my $dir;
BEGIN {
    $dir = dirname(__FILE__);
}
use lib "$dir/folder1";
use my_library_2;

Upvotes: 0

Related Questions