Perl modules are sometimes located in non-standard directories. There are several ways to use these modules:
- Add the directory to the PERL5LIB environment variable.
- Run the script using the perl -l.
- Within the script ‘use lib‘ with the directory name.
These methods are quite common and handle most of the cases perfectly.
For example:
#!/usr/bin/perl -w
use strict;use lib (“/home/users/yuval/perl/modules”);
use MyModule;…
This works fine as long as you know that you need to search in /home/users/yuval/perl/modules to find MyModule.
But what happens if you don’t know the location of the module ahead of time?
None of the methods mentioned above can handle this situation. Consider the following code:
#!/usr/bin/perl -w
use strict;my $user = GetCoolestUser();
use lib (“/home/users/$user/perl/modules”);
use MyModule;sub GetCoolestUser()
{
return “yuval”;
}…
Running this code gives a bunch of really scary compilation errors.
Yes – compilation errors. Yes – in Perl. What gives you ask?
The reason is that the Perl compiler tries to locate all of the modules that are going to be loaded before running the script. It does this before values are given to any variables, and before any functions are evaluated. Therefore the $user variable is undefined when it is evaluated in the parameters to the ‘use lib‘ statement, and then MyModule isn’t found in any of the directories that Perl searches.
There are two ways around this:
1. Push the directory name directly into the @INC array in the BEGIN function
#!/usr/bin/perl -w
use strict;
BEGIN
{
sub GetCoolestUser()
{
return “yuval”;
}
my $user = GetCoolestUser();
push(@INC, “/home/users/$user/perl/modules”);
}
use MyModule;…
You may notice that this code doesn’t use the elegant ‘use lib‘ but rather the tasteless pushing of the directory into the @INC array. Also – the GetCoolestUser function has to be defined within the BEGIN block in order to be used.
2. Use the eval function
#!/usr/bin/perl -w
use strict;my $user = GetCoolestUser();
eval “use lib qw(/home/users/$user/perl/modules);
use MyModule;”;
if ($@) {
die “Error loading module MyModule:\n$@\n”;
}sub GetCoolestUser()
{
return “yuval”;
}…
This method “tricks” Perl compiler and allows loading the module from any location you wish. This method is stronger than the previous method mentioned because the module loading occurs during run time and the location can be calculated dynamically during run time as well.