A proper way of using Perl custom modules inside of other Perl modules

eclipse, epic, include, module, perl

Solution

I strongly disagree with modifying `@INC` in modules. It causes all kinds of headaches. Let the script (or even the calling process via the `PERL5LIB` environment variable) setup `@INC` correctly.

`script.pl`:

use FindBin qw( $RealBin );
use lib
   "$RealBin/../ModulesFolder1",
   "$RealBin/../ModulesFolder2";

use ModuleInFolder1;

`ModuleInFolder1.pm`:

use ModuleInFolder2;  # Works fine.

As for EPIC, do the following:

- Right-click on the project.

- Properties

- Perl Include Path

- `${project_loc}/ModulesFolder1`, Add to list

- `${project_loc}/ModulesFolder2`, Add to list

(I literally mean the 14 chars `${project_loc}`. That means something to EPIC. It will continue to work even if you move the project.)

PS — `$RealBin` is better than `$Bin` because it allows you to use a symlink to your script.

PS — `__FILE__` is more appropriate than `$INC{'ThisModule.pm'}`.

Problem

I'm using custom modules in my scripts and have to store them outside of Perl `lib` directory. So in Perl scripts (`*.pl`) I use the following block to include them in `@INC`: ``` BEGIN { use FindBin qw($Bin); push @INC, "$Bin/../ModulesFolder1"; push @INC, "$Bin/../ModulesFolder2"; } ``` But I also have to use modules inside of my other Perl modules (`*.pm`), and as I understand `FindBin` works for scripts only. So I change that block to: ``` BEGIN { push @INC, catdir( dirname( $INC{'ThisModule.pm'} ), qw( .. ModulesFolder1 ) ); push @INC, catdir( dirname( $INC{'ThisModule.pm'} ), qw( .. ModulesFolder2 ) ); } ``` It works but with a little problem. I code in Eclipse with EPIC plugin, and "if you have something in a BEGIN block that causes the compiler to abort prematurely, it won't report syntax errors to EPIC", so that way I loose Perl syntax check in modules. So, with `FindBin` (in scripts) I don't have to use any functions (like `catdir`) in `BEGIN{}` block, and the syntax check of the following code goes on correctly. Besides, I'd like not to change any environment variables (like `PERL5LIB`), so that I could use the scripts on my colleagues' machines without any additional preparations. What's the proper way of using custom Perl modules inside of other modules, and not interfering with EPIC syntax check at the same time? Or maybe I even should include modules in completely other way?

Original source