Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Creative way to include custom modules without eval?

by IronCladLou (Initiate)
on Oct 26, 2012 at 14:30 UTC ( #1001090=perlquestion: print w/ replies, xml ) Need Help??
IronCladLou has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I'm looking for some wisdom regarding inclusion of custom libs in a project. Bear with me, for this problem is a bit trickier than just a simple:

use lib qw(/path/to/my/libs);

In all of my searching, I have not found a good answer for this one, so perhaps the enlightened can assist?

First, the restrictions for this project:

  1. Modules which need to be compiled may NOT be installed.
  2. Custom modules may NOT be added to the system lib paths.
  3. Environment variables may NOT be modified.
  4. The MyApp package can be installed anywhere on a system.

Next, a visual to understand the contents of the project.

~/MyApp |_ /1.0 |_ /1.1 |_ /1.2 |_ /bin |_ script1.pl |_ /util |_ script2.pl |_ /lib |_ /perl |_ Module1.pm |_ Module2.pm |_ /plugins |_ /default |_ plugin1.pl |_ /custom |_ plugin2.pl |_ plugin3.pl |_ /Dir1 |_ Dir2 |_ plugin4.pl

Every perl script in /bin and /plugins needs to have access to the custom modules in ~/lib/perl, regardless of how deep into the directory tree the script is.

To tackle this problem, I have been adding the following block to the header of all the scripts. Basically, I climb the directory tree, until I find the toplevel that looks like the version number, "1.2", and then include /lib/perl from there.

use strict; use warnings; use File::Spec; use Cwd 2.17 qw(realpath); eval { use lib (eval { my @dirs = File::Spec->splitdir( (File::Spec->splitpath(realpath($0)))[1] ); while (scalar(@dirs) and $dirs[-1] !~ /\d+\.\d+/) { pop(@dirs); } return File::Spec->join(@dirs, 'lib', 'perl'); } ); use Module1; use Module2; }; if ($@) { die "Failed to load custom modules.\n"; }

It works perfectly, but it looks and feels clunky. Also, the eval{} blocks raise eyebrows, and I'd feel better if they weren't there.

Is there a cleaner way to do this? Can I get rid of the eval{} blocks completely? Have I overlooked a much simpler way to do this?

--Many Thanks!

Comment on Creative way to include custom modules without eval?
Select or Download Code
Re: Creative way to include custom modules without eval?
by tobyink (Abbot) on Oct 26, 2012 at 14:36 UTC

    I'm pretty sure that FindBin::libs could help you out here.

    Either way, the evals seem a bit pointless. do would do the trick...

    use strict; use warnings; use File::Spec; use Cwd 2.17 qw(realpath); use lib do { my @dirs = File::Spec->splitdir( (File::Spec->splitpath(realpath($0)))[1] ); pop @dirs while (scalar(@dirs) and $dirs[-1] !~ /\d+\.\d+/); File::Spec->join(@dirs, 'lib', 'perl'); }; use Module1; use Module2;
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      Ah! Many thanks, tobyink.

      That is a much nicer block of code. Using 'do' never even occurred to me!

      +10 Karma points for you.

Re: Creative way to include custom modules without eval?
by Anonymous Monk on Oct 26, 2012 at 15:29 UTC
Re: Creative way to include custom modules without eval? (FindLib)
by tye (Cardinal) on Oct 27, 2012 at 06:09 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1001090]
Approved by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (11)
As of 2014-12-18 09:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (48 votes), past polls