Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

use lib $lib_dir not working

by karelb (Novice)
on Apr 27, 2011 at 09:48 UTC ( [id://901512]=perlquestion: print w/replies, xml ) Need Help??

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

Holy Monks, I seek your wisdom on the following issue. I have a perl script that has a private library installed in the directory ../lib. However the perl script runs from a cronjob with its full path name and use lib '../lib' is therefore not working. Hence I made the following construct to get the actual library path:
@dirs = split('/',$0); splice(@dirs,-2); $install_dir = join('/',@dirs); $lib_dir = $install_dir."/lib";
So far so good, but any monk already can guess what the problem is going to be: use lib $lib_dir I understand why this is not working (compile time etc), but I have no clue how to solve this.

Replies are listed 'Best First'.
Re: use lib $lib_dir not working
by Corion (Patriarch) on Apr 27, 2011 at 09:49 UTC

    Pull up your code from run time to compile time by using a BEGIN block:

    BEGIN { ... } use lib ...;
      Thanks for the suggestion and I already tried something like that. But it reports a problem with the splice line: "Modification of non-creatable array value attempted, subscript -2". I guess this is because $0 is not defined inside the BEGIN block.
        No; guess again.

        The problem is with @dirs. Did you assign it in the BEGIN block? If you declare it with "my", make sure you do that in outside the BEGIN block. the actual use line should also be outside (after) that block. And is $0 actually the full path? I think perhaps your @dirs array is just too short for the splice. You might have to use rel2abs to make it so.

        Anyway, I would do it another way, and put the code in a do block. Untested:

        use File::Spec::Functions qw(rel2abs) use lib do { my @dirs = split('/', rel2abs($0)); splice(@dirs,-2); my $install_dir = join('/',@dirs); $install_dir."/lib" };
Re: use lib $lib_dir not working
by wind (Priest) on Apr 27, 2011 at 09:59 UTC

    The following should work for you:

    require lib; use Cwd qw(abs_path); use File::Basename qw(dirname); BEGIN { my $dirname = dirname($0); my $perl = abs_path("$dirname/../lib"); lib->import($perl); }

    Here's a related question from earlier this year that will have other solutions: adding library directories relative to $0

      @wind: Thanks a lot, that works for me.
Re: use lib $lib_dir not working
by tinita (Parson) on Apr 27, 2011 at 10:34 UTC

      This is an excellent suggestion.   FindBin will tell you where the script is actually executing.   It gives you a string, and you can go from there.

      It is a good idea to specify, one way or the other, fully qualified path names.

      This is the solution I used to go with. However, I happened upon one of tye's rants in the CB a number of years ago, where he pointed out that FindBin is broken, and that you're better with File::Spec->rel2abs($0).

      I actually have the following in one of my scripts:

      use File::Spec; use File::Basename qw(dirname); use Cwd qw(abs_path); use lib File::Spec->catdir(dirname(dirname(abs_path($0))),'lib');
      Not necessarily the best way to do it, but close enough, I figure. And probably faster than FindBin

        that FindBin is broken

        well. the objections against FindBin I read so far always have to do with using FindBin after you changed the directory. If I had a script somewhere in my repository that does a chdir in a BEGIN block and if such a weird thing is really necessary, I can place FindBin even before that BEGIN block and everything's fine. If the script uses a module that does a chdir in a BEGIN block then I probably have other problems anyway.

        So if you know what you're doing IMHO FindBin is handy and safe enough. Do you always use $[ instead of 0 just because a script could set it somewhere? ;-)

        A reply falls below the community's threshold of quality. You may see it by logging in.
        Now I think I understood the problem. It is about the PATH searching feature which is only invoked if the script is called via "perl perlscript.pl". (Documented is a workaround to call "perl ./perlscript.pl", though. I guess I never had problems with this because I usually call scripts with the full path or at least bin/script.pl anyway.)

        I was informed by Graham Barr that the PATH searching was done only because of a broken SunOS shell many years ago. I asked him because I suspected there must have been a reason for this.

        Moritz and I discussed and came to the conclusion that there is no other case where this "feature" would actually be reliable and useful. So to keep the nice short usage of FindBin and to make it work correctly in all cases (except doing chdir() before, since it is actually impossible to obtain the correct path then) I submitted a report to perlbug:
        http://rt.perl.org/rt3//Public/Bug/Display.html?id=89698

        update: link corrected, thanks
        use Path::Class; use lib dir( $0 , qw'.. .. lib')->absolute; use lib dir( file( $0 )->dir->parent, 'lib')->absolute;
Re: use lib $lib_dir not working
by Anonymous Monk on Apr 27, 2011 at 10:13 UTC
    • $ perl -le " use lib do { my @She = qw[ wah diddy diddy dum diddy do ] +; $She[ rand @She ]; }; print for @INC " diddy C:/perl/site/5.12.2/lib/MSWin32-x86-multi-thread C:/perl/site/5.12.2/lib C:/perl/5.12.2/lib/MSWin32-x86-multi-thread C:/perl/5.12.2/lib .
    • use File::Spec; use File::Basename qw' dirname '; BEGIN { my $thisf = File::Spec->rel2abs(__FILE__); my $thisd = dirname($thisf); use lib File::Spec->catfile( $thisd, File::Spec->updir, 'lib' ); }
    • use Path::Class; BEGIN { my $thisf = file(__FILE__)->absolute; my $thisd = $thisf->dir; use lib dir( $thisd, '..','lib' ); }
    • use Path::Class; use lib dir( __FILE__, '..','..','lib')->absolute->resolve;

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (3)
As of 2024-04-26 05:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found