Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can my Perl script find its module in the same directory?

People also ask

What is Findbin in Perl?

This allows a user to setup a directory tree for some software with directories <root>/bin and <root>/lib , and then the above example will allow the use of modules in the lib directory without knowing where the software tree is installed.

Where is @INC in Perl?

Perl interpreter is compiled with a specific @INC default value. To find out this value, run env -i perl -V command ( env -i ignores the PERL5LIB environmental variable - see #2) and in the output you will see something like this: $ env -i perl -V ... @INC: /usr/lib/perl5/site_perl/5.18.

What is use lib in Perl?

It is typically used to add extra directories to Perl's search path so that later do, require, and use statements will find library files that aren't located in Perl's default search path.


I am curious why the simplistic solution

use File::Basename;
use lib dirname (__FILE__);
use SomeModuleLocatedInTheSameDirectoryAsThisPerlScriptOrModule;

did not come up. The FindBin module seems to have some issues if the file is not the main executable perl script, but simply a non-executable Perl module. At least that's how I interpret the comment in the documentation. Did not really test it.

To have any other path relative to the location of this Perl file, do something like

use File::Basename;
use lib dirname (__FILE__) . "/MyModules";

The simplest approach I found it to use FindBin module. Like this:

use FindBin;
use lib $FindBin::Bin;

Generally I prefer to have my scripts provided in such a way that programs are in whatever/bin, and libraries are in whatever/lib

In these situations I use a slightly more complicated approach:

use Cwd qw(abs_path);
use FindBin;
use lib abs_path("$FindBin::Bin/../lib");

The abs_path call is to make the @INC contain whatever/lib, and not whatever/bin/../lib - it's just a slight change, but makes reading error messages easier.


From perlfaq8, which answers "How do I add a directory to my include path (@INC) at runtime?". There are several other answers for questions around this issue too.


How do I add a directory to my include path (@INC) at runtime?

Here are the suggested ways of modifying your include path, including environment variables, run-time switches, and in-code statements:

the PERLLIB environment variable

$ export PERLLIB=/path/to/my/dir
$ perl program.pl

the PERL5LIB environment variable

$ export PERL5LIB=/path/to/my/dir
$ perl program.pl

the perl -Idir command line flag

$ perl -I/path/to/my/dir program.pl

the use lib pragma:

use lib "$ENV{HOME}/myown_perllib";

The last is particularly useful because it knows about machine dependent architectures. The lib.pm pragmatic module was first included with the 5.002 release of Perl.


Besides the already stated solutions:

  1. use FindBin / lib
  2. Perl Faq 8 How do I add a directory to my include path (@INC) at runtime?

'The simplest approach' (™) that I use while dev/testing a module prior to deploying it (in /usr/local/lib/site_perl/ or elsewhere in @INC) is to modify @INC before loading the module as follows:

#!/usr/bin/perl
use strict;
use warnings;
# Modify @INC prior to module loading.
BEGIN { unshift @INC, '.'; }
use YourModuleInCWD;

(Add current working directory to @INC? - PerlMonks)


You can make perl look in any directory by using the -I flag. Here, -I stands for @INC which is the array of paths in which perl looks for modules. Using -I adds the given path to the @INC array for this execution.

eg:

perl -I lib bin/script.pl

where lib contains the modules I want to use.

I know that this works for perl 5. I am not at sure about other versions.


Take a look at Par::Packer. It creates an executable with all of the script's dependencies included. It makes distribution easy. You also could also provide your users a version of your module that can be installed on their systems. See Module::Starter for an easy way to build all of the files required to make a standard CPAN-style distribution.