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

adding library directories relative to $0

by perl5ever (Pilgrim)
on Feb 22, 2011 at 20:47 UTC ( #889674=perlquestion: print w/replies, xml ) Need Help??
perl5ever has asked for the wisdom of the Perl Monks concerning the following question:

Lately I've been finding myself adding library directories which are relative to $0. For instance, if the program '.../bin/foo' needs to use pm files in '.../lib', I'll have this at the beginning of 'foo':
use File::Basename; use Cwd 'abs_path'; BEGIN { unshift(@INC, abs_path(dirname($0).'/../lib')); };
Question: Is there a standard module which does this? It would be nice if one could write something like:
use rellib '../lib';
instead of that boilerplate mess above.

If not, has a module which does this ever been considered for inclusion as a standard module?

Naturally, such a module could be made to work like 'use lib' in that it would include arch specific directories if they exist.

Replies are listed 'Best First'.
Re: adding library directories relative to $0
by jeffa (Bishop) on Feb 22, 2011 at 20:57 UTC

    FindBin is a standard module that solves this problem. (sort of)

    use FindBin qw($Bin); use lib "$Bin/../lib";


    (the triplet paradiddle with high-hat)
Re: adding library directories relative to $0
by ikegami (Pope) on Feb 22, 2011 at 21:59 UTC

    Find::Lib appears to be exactly that.

    use Find::Lib '../lib';

    By the way, you have abs_path (aka realpath) and dirname backwards.

    use Cwd qw( abs_path ); use File::Basename qw( dirname ); use lib dirname(abs_path($0)).'/../lib';

    The order in which you use them will fail if you create a symlink to the script.

    Update: Find::Lib touts its handling of symlinks, but it fails to handle a symlink to the script.

    $ find ! -type d -exec ls -l {} + lrwxrwxrwx 1 eric users 8 Feb 22 17:04 ./ -> bin/ -rwx------ 1 eric users 53 Feb 22 17:04 ./bin/ -rw------- 1 eric users 16 Feb 22 17:03 ./lib/ $ cat bin/ #!/usr/bin/env perl use Find::Lib '../lib'; use Mod; $ cat lib/ package Mod; 1; $ bin/ $ Can't locate in @INC (@INC contains: /home/eric/usr/perlbrew/pe +rls/perl-5.12.2/lib/site_perl/5.12.2/i686-linux /home/eric/usr/perlbr +ew/perls/perl-5.12.2/lib/site_perl/5.12.2 /home/eric/usr/perlbrew/per +ls/perl-5.12.2/lib/5.12.2/i686-linux /home/eric/usr/perlbrew/perls/pe +rl-5.12.2/lib/5.12.2 .) at ./ line 3. BEGIN failed--compilation aborted at ./ line 3.
Re: adding library directories relative to $0
by wind (Priest) on Feb 22, 2011 at 21:11 UTC

    I do the same thing in certain scripts, so would be curious if someone suggested another solution.

    Also, I use __FILE__ instead, to ensure that it's relative to the current file instead of the executing script.

    # use lib <Relative Directory> use lib; use Cwd qw(abs_path); use File::Basename qw(dirname); BEGIN { my $dirname = dirname(__FILE__); my $perl = abs_path("$dirname/../../perl"); lib->import($perl); }
      It seems very odd to me that you would want to add to @INC in anything but the executing script.


        I think he meant it as a way to avoid something like:

        $ mkdir -p TEST/{bin,sl}/lib $ echo -e "package myLib;\nour \$VERSION=1.1;\n" >TEST/sl/lib/ $ echo -e "package myLib;\nour \$VERSION=1.7;\n" >TEST/bin/lib/myLib.p +m $ cp TEST/bin $ cd TEST/bin $ ./ myLib version: 1.7 search path: /home/marco/TEST/bin/lib /etc/perl /usr/local/lib/perl/5.10.1 . . . $ cd ../sl $ ln --symbolic ../bin/ printval $ ./printval myLib version: 1.1 search path: /home/marco/TEST/sl/lib /etc/perl /usr/local/lib/perl/5.10.1 . . . $ cat ../bin/ #!/usr/bin/perl use strict; use warnings; use File::Basename; use Cwd 'abs_path'; my $f; BEGIN { unshift(@INC, abs_path(dirname($0).'/lib')); } use myLib; print "myLib version: ", $myLib::VERSION, "\n"; print "search path: ", join("\n", @INC[0 .. 2], "\t. . ."), "\n";


        When your only tool is a hammer, all problems look like your thumb.

Re: adding library directories relative to $0
by fullermd (Priest) on Feb 23, 2011 at 05:50 UTC

    I use lib with that sort of thing all the time by going through a variable...

    my $rundir; BEGIN { use File::Basename; $rundir = dirname($0); } use lib "$rundir/lib";

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://889674]
Approved by Corion
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (7)
As of 2017-01-20 07:14 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (173 votes). Check out past polls.