Is there any way to set the perl library search path to the path that holds the perl script at compile-time? In other words, I'd like it so that I can keep my perl scripts and perl modules (.pm) in the same (arbitrary) subdirectory and have it work by just executing the script.

It would be something similar in intention to:

use lib File::Basename::dirname($0);

except that the previous line doesn't work because use lib is evaluated at compile-time.

Recommended Answers

All 7 Replies

I think you can do something crazy (I do this) by just pushing values onto inc, such as:

push(@INC, '.');

Which adds the current directory (.) to the INC (search path) of Perl. You should be able to any path, but I haven't tried. I know . works, but I'm pretty positive you can add any permissable (given permissions) path.

push(@INC, '/home/yourname/path2yourpms');

Let me know how that turns out.

push(@INC, '/home/yourname/path2yourpms');

Let me know how that turns out.

Unfortunately this doesn't seem to work for variables. I tried this before with the following code:

#!/usr/bin/perl -w -C

use File::Basename;
$dirname = dirname($0);
push @INC, $dirname;
#use lib $dirname;
use MyPackage;

It still couldn't find my perl module. In fact, along with the error is a list of the elements of @INC that contains and the directory wasn't there.

Any other ideas? I just need for the perl script to find the module in whichever subdirectory the executing script's in.

I don't understand your problem. If your perl script and your perl module are in the same directory, then just 'use' the module. For example, I had a 'grouper.pl' and a 'CSV.pm' file in the same directory. The 'grouper.pl' contained the line,

use CSV;

and it works. It's supposed to work.

I don't understand your problem. If your perl script and your perl module are in the same directory, then just 'use' the module. For example, I had a 'grouper.pl' and a 'CSV.pm' file in the same directory. The 'grouper.pl' contained the line,

use CSV;

and it works. It's supposed to work.

It doesn't work if your current working directory is not the same subdirectory as the perl script's and module's. (The reason it works is that '.' is in @INC.)

My situation is that the perl script can (and will) be mounted on different subdirectories so an absolute path is out of question inside the script. I'm deploying this to simple folk so I'm trying to make it a simple "execute the program by specifying its full path" kind of command.

Worse comes to worst, I'll probably insert a Bourne shell script to set the PERLLIB environment variable, but I'd really hate to think there's something perl alone couldn't do. Specially something this simple.

See if this works. Try placing this at the very top of your perl script:

BEGIN
{
use File::Basename;
unshift(@INC, dirname($0));
}

It doesn't work if your current working directory is not the same subdirectory as the perl script's and module's. (The reason it works is that '.' is in @INC.)

My situation is that the perl script can (and will) be mounted on different subdirectories so an absolute path is out of question inside the script. I'm deploying this to simple folk so I'm trying to make it a simple "execute the program by specifying its full path" kind of command.

Worse comes to worst, I'll probably insert a Bourne shell script to set the PERLLIB environment variable, but I'd really hate to think there's something perl alone couldn't do. Specially something this simple.

I was going to suggest a BEGIN{} block too. Perl will compile a BEGIN{} block as soon a possible so it should work.

Yes place the push/unshift @INC in a BEGIN block, or change use MyModule to require MyModule.

The keyword use forces inclusion of the module at compile time, so modifications of the @INC list (AFAIK) has no effect for a use, but a require doesn't include the module until "runtime", or when it is actually needed, so modifications of @INC will be heeded.

Since a BEGIN block is the first thing compiled, use should be able to use a modified @INC list that is modified in a BEGIN block, but it won't (AFAIK) be able to use a modified @INC that is modified outside of a BEGIN block.

Edit: Unless of course that use is wrapped in an eval statement. Then you can use an @INC list that is modified outside of a BEGIN block as well.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.