h3g0r_ h3g0r_ - 2 months ago 6
Perl Question

External conf file in perl module

I'm pretty new in Perl and need an advice for this, please.

I have a script Script.pl in a "Path 1".
Beside, I have a module ModuleA.pm in a "Path 2".
Finally, I have a common module ModuleB.pm in a "Path 3". This ModuleB is common and other script in other path use it.
All path are differents. The Script.pl use the ModuleA, and the ModuleA use the ModuleB.

I need put a external file of configuration in the ModuleB. This conf file is in the same "Path 3". The conf.cfg is require in the ModuleB:

use strict;
require "conf.cfg";

How can I include the conf.cfg in the ModuleB as a dynamic way?, because if I compile the Script.pl, doesn't compile because can't find the conf.cfg, because now ModuleB path is "Path 1" and in the "Path 1" doesn't exist the conf file.

So I need require the conf file independently of the *.pl and path that use the ModuleB.

I was clear enough?

Thanks in advance.


Update   Added at the end -- Get the ModuleB path at runtime for require, to avoid hard-coding it since the module's location may be moved in updates.

Specify the full path for conf.cfg when requiring it.

Consider the following hierarchy and files, where all paths start from /path/


The main script.pl

use warnings;
use lib '/path';
use Path2::ModuleA;

File Path2/ModuleA.pm

package ModuleA;    
use warnings;
use Path3::ModuleB;

File Path3/ModuleB.pm

package ModuleB;
use warnings;
require "Path3/conf.cfg";

File Path3/conf.cfg

use feature 'say';
say "This is conf.cfg";

Running the script.pl (from inside Path1/) prints the line This is conf.cfg

Note the line use lib '/path', where /path is a literal string specifying the path to directory from which Path2 and Path3 start. See lib pragma

It is typically used to add extra directories to perl's search path so that later use or require statements will find modules which are not located on perl's default search path.

Using library path relative to where the script is can be made easier. In script.pl

# Load relative path for modules.
use FindBin qw($Bin);
use lib "$Bin/../lib";
use Path2::ModuleA;
# ...

In this case Path2 (etc) for modules start in the directory ../lib, relative to where the script is


where I picked the name bin just as an example. See the core module FindBin.

This quick note barely scratches the surface of how modules can be organized.

A specific constraint emerged in comments. The ModuleB lives in a path that may change with future updates, thus hard-coding that path in the require statement is not optimal.

One solution is that the path is found inside ModuleB at runtime and that used in the require. This can be done using Perl's special literal __FILE__.

File Path3/ModuleB.pm

package ModuleB;

use warnings;
use strict;
use Cwd qw(abs_path);    

my ($this_dir) = abs_path(__FILE_) =~ m|(.*)/|;

require "$this_dir/conf.cfg";


The abs_path from the core module Cwd is needed since __FILE__ may not return the absolute path. The regex used to find the directory itself matches everything up to a / greedily, all the way up to the last / -- thus the whole path without the filename itself. Instead of doing that you can use functions from either of the File::Spec or File::Basename core modules.