tags:

views:

101

answers:

3

In my app, I put all the modules in one directory , let's just call it libx. Since it's up to the user to choose where to deploy the app, I don't want to hardcode the lib path.

So at the beginning of myapp.pl, I wrote the following lines of code.

#! /usr/bin/perl -w
use strict;

my $curr_dir = $0;
my $curr_lib = $curr_dir;
$curr_lib =~ s/myapp\.pl/libx/;

use $curr_lib ;

Instead of getting what I'm expecting, I got compiling errors!

So what's wrong with my code? I don't want to hardcode the lib path when using use lib, how should I do this?


Sorry I forgot to mention that when the app is deployed, myapp.pl and libx are in the same directory.

+2  A: 

I had trouble with this before too. What's happening is that Perl makes two passes over your code: once to compile it, and the second time to run it. In you example, lines 4,5, and 6 don't execute until run time, but use takes effect during compile time.

One possibility is to put it all inside a BEGIN{} block, which will make the code execute at compile time. I've done this, but it's messy/ugly. (BTW, instead of $0, you need to use $ARGV[0] in Perl).

The best way to tell Perl where to pick up libraries is to use the -I flag. You can put it on the #! line, or if you are starting the script from another script, you can start it as

perl -I/your/directory/libx your_script.pl

You can use relative paths, so maybe

perl -I./libx script.pl

would work for you.

It would help if you told us exactly how you expect your user to start the app. Will they just type 'myapp.pl', and it's up to them to have $PATH set so that myapp.pl can be found in whatever directory they stuck it?
+15  A: 

use happens at compile-time, not run-time, so your variable hasn't been set yet. You can do:

my $curr_lib;
BEGIN {
    $curr_lib = $0;
    $curr_lib =~ s/myapp\.pl/libx/;
}    
use lib $curr_lib;

or you could:

use FindBin;
use lib "$FindBin::Bin/libx";
ysth
+1  A: 

use xxx is a compile-time directive, not a run-time instruction. You cannot set it programmatically within the script you are running.

You may need to try require rather than use

If you need use, you need to set your $PERL5LIB environment variable to ensure your modules are correctly located and used, or change your shebang line to read #! /usr/local/perl -w -I/path/to/libx. There are other methods (local::lib etc.), but from your question it seems your control over installation is a bit limited for that sort of approach.

RET
This not 100% true, you can use a string `eval` to execute a `use` at runtime.
Chas. Owens