http://www.perlmonks.org?node_id=373398

bradcathey has asked for the wisdom of the Perl Monks concerning the following question:

Good monks:

I have a group of scripts that comprise a small CMS that I install for various customers. Each script (there are 12 so far) starts with

#!/usr/bin/perl -T use lib "/home/username/www/perllib"; use Validate; #little module for validating form input etc.

This means that each time I install it I have to physically edit each use lib statement. It would be nice to have one place to edit. I naively tried to keep the path in a text file and insert it as a variable:

#!/usr/bin/perl -T my $pathtolib = &opentextfile; use lib $pathtolib;

and even crazier:

#!/usr/bin/perl -T my $pathtolib = &opentextfile; eval(use lib $pathtolib);
I found a module called "FindBin" which I read about in the "Cookbook" but my host doesn't have it installed (I'm not sure it would find my modules as they are in an unconventional directory, not related to the cgi-bin file--but that is conjecture since I can't even try it at this time). Anyway, is this possible by some other means? Thanks.

—Brad
"Don't ever take a fence down until you know the reason it was put up. " G. K. Chesterton

Replies are listed 'Best First'.
Re: Variable to point to library?
by pbeckingham (Parson) on Jul 10, 2004 at 21:32 UTC

    Can you use $0, and manipulate it to create $pathtolib, as $0 will already have a user-specific path?

      Interesting. I just read up on $0 in the Camel and it says assignment to it "is magical," but no examples. If you had a sec, a line of code to see how this is done would be appreciated. Thanks.

      —Brad
      "Don't ever take a fence down until you know the reason it was put up. " G. K. Chesterton

        Perhaps something like...

        use File::Basename; use File::Spec; my $pathtolib = File::Spec->rel2abs (dirname $0);

Re: Variable to point to library?
by perldeveloper (Scribe) on Jul 10, 2004 at 21:36 UTC
    If I were you, I'd create an environment variable which holds the location of all my perl scripts (say WWW_PERLLIB). This does usually imply editing a file, at least under Linux (/home/username/.bash_profile). Then use Perl's mechanism to extract the environment variable's value ($ENV{$variable}) like this:
    use lib $ENV{"WWW_PERLLIB"}; use Validate; ...
      Nice idea, except there already is one, it's called PERL5LIB, which perl automatically looks for and adds to its @INC (lib path array). Thus removing the need for 'use lib' at all.

      C.

        Doesn't this assume a cgi version of Perl? How about if using mod_perl?
Re: Variable to point to library?
by perrin (Chancellor) on Jul 10, 2004 at 23:06 UTC
    FindBin is part of the standard library, so your host must have it installed. That's a good way to go. Aleternatively, the contents of the environment variable PERL5LIB are always added to the include path, so you could just set that in your .bashrc or equivalent.
Re: Variable to point to library?
by orderthruchaos (Scribe) on Jul 12, 2004 at 17:52 UTC
    I actually prefer using MakeMaker (and h2xs) to perform this kind of task. MM allows you to specify perl programs to run at compile time as arguments to the WriteMakefile() routine:
    WriteMakefile( NAME => 'Test::Bin', VERSION_FROM => 'lib/Test/Bin.pm', # finds $VERSION PREREQ_PM => {}, # e.g., Module::Name => 1.1 PL_FILES => { 'bin/test.PL $(INSTALLSITELIB) $(INSTALLSITEARCH)' => 'lib/Test/Bin.pm' }, );
    The PL_FILES attribute allows you to specify the .PL files and which files they should modify. I add the $(INSTALLSITELIB) $(INSTALLSITEARCH) as arguments so the perl program will receive those macros from the makefile. Then, for example, I would transform a package like the following:
    package Test::Bin; use 5.008002; use strict; use warnings; use '###LIBPREFIX###'; # Use some easily matchable phrases use '###ARCPREFIX###'; 1; __END__
    by using this .PL file:
    #!/usr/bin/perl -w -pi~ # Use command line options to read and write file(s). use strict; our ($lib, $arc); BEGIN { $lib = shift @ARGV; # Shift off the arguments so they are $arc = shift @ARGV; # not processed as files } s/\Q###LIBPREFIX###\E/$lib/; # perform substitutions s/\Q###ARCPREFIX###\E/$arc/; 1; __END__
    The end result is at least similar to what you are looking for:
    package Test::Bin; use 5.008002; use strict; use warnings; use '/home/orderthruchaos/local/lib/perl5/site_perl/5.8.2'; use '/home/orderthruchaos/local/lib/perl5/site_perl/5.8.2/i686-linux'; require Exporter; our $VERSION = '0.01'; 1; __END__
    Hope this helps.
Re: Variable to point to library?
by benizi (Hermit) on Jul 12, 2004 at 23:15 UTC

    The problem is that 'use' statements get wrapped in BEGIN blocks, so $pathtolib isn't set by the time 'use lib' needs it. Here's how you can accomplish what you're looking for:

    #!/usr/bin/perl my $pathtolib; BEGIN { $pathtolib = &opentextfile; } # opentextfile must be defined b +efore this line use lib $pathtolib;

    or even:

    #!/usr/bin/perl # define opentextfile somehow use lib &opentextfile;