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:
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/Path1/script.pl /path/Path2/ModuleA.pm /path/Path3/ModuleB.pm /path/Path3/conf.cfg
The main script.pl
use warnings; use lib '/path'; use Path2::ModuleA;
package ModuleA; use warnings; use Path3::ModuleB; 1;
package ModuleB; use warnings; require "Path3/conf.cfg"; 1;
use feature 'say'; say "This is conf.cfg";
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
Path3 start. See
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
# 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
./bin/script.pl ./lib/Path2/ModuleA.pm ./lib/Path3/...
where I picked the name
bin just as an example. See the core module
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
package ModuleB; use warnings; use strict; use Cwd qw(abs_path); my ($this_dir) = abs_path(__FILE_) =~ m|(.*)/|; require "$this_dir/conf.cfg"; 1;
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::Basename core modules.