pupil
pupil

Reputation: 185

Include perl module from a different location

my problem is as follows

  1. I have the lib in location ./abc/def/lib
  2. I am using it in path ./abc/xyz/lib/tuv/abc.pm

I am running the code from a different location altogether which is something like ./abc/xyz/blah1/blah2/../../ . I'm running the code here.

I have created env params

setenv def ./abc/def 
setenv xyz ./abc/xyz

I tried the below solutions

  1. Begin { push(@INC, $ENV{def}."/lib" ) }
    Along with the providing the path for other libraries i used use lib $ENV{xyz}."/lib"

    This solution didn't work. I get the error saying the library in ./abc/def/lib is not included.

  2. I tried the FindBin

    # for the libs present in ./abc/def/lib
    use FindBin;
    use lib "$FindBin::Bin/../../";
    use mylib::abc;
    use mylib::def;
    

(I tried giving the path also of root from where to start looking..in FindBin)

I tried using different combinations but not sure why it doesn't work. Can someone point out what i am doing wrong or is my understanding of FindBin wrong.

Upvotes: 5

Views: 426

Answers (2)

Dave Cross
Dave Cross

Reputation: 69224

You don't say what problems you're having. Just saying you're "not sure why it doesn't work" isn't really helpful. I assume you're getting a "Can't locate [some module] in @INC" error.

There are three (recommended) ways to change the value of @INC. Each have their uses.

  • Inside a program, you can use use lib
  • From the command line (or in a shebang), you can use -I
  • In your shell environment, you can set PERL5LIB

In all these cases, the new directories will be added to the start of @INC, so these directories will be searched before the standard library directories.

You can also manually manipulate @INC. Note that in order for manual manipulation of @INC to have any effect on use statements in your code, they will need to be executed in a BEGIN block (as use statements are executed at compile time). It looks like you have tried that too, but that you used Begin rather than BEGIN - which wouldn't work.

If you are running your program from a location that is completely unrelated to the directories where the libraries are kept, then FindBin is likely to be of limited use. FindBin is useful where the location of the executable file and the libraries are closely related (for example the executable file is in ./bin and the libraries is in ./lib).

It also seems that you are trying to adjust @INC from within a library (./abc/xyz/lib/tuv/abc.pm). Note that FindBin will not set $FindBin::Bin to this directory. $FindBin::Bin is always set to the directory that contains the executable file which is running.

Without knowing more about the actual paths that you are using (you have only given relative paths in your examples) it's hard to know for sure what the best approach is. But I think that in your situation I'd be setting PERL5LIB to the absolute path of your extra libraries.

Upvotes: 3

Grant McLean
Grant McLean

Reputation: 6998

The FindBin module is the best fit for your needs. The important thing to remember is that $FindBin::Bin refers to the directory that contains the script. So when you refer to it ...

use lib $FindBin::Bin . '/../../etc';

the '/../..' path must describe the path from the script directory to the lib directory.

The other important thing to take into consideration is the error message. It will start with Can't locate Your/Module/Name.pm but will then go on to list all the directories in @INC - the library search path. Check this list of directories to make sure it includes the lib path you intended to add.

Upvotes: 0

Related Questions