http://qs321.pair.com?node_id=1222924

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

Greetings Monks,

I am trying to use a module from CPAN.

use Excel::Writer::XLSX;

I installed the module locally with command

perl -MCPAN -Mlocal::lib -e 'CPAN:install(Excel::Writer::XLSX)'

I could locate the required module in the dir

~/perl5/lib/perl5/Excel/Writer/XLSX.pm

So, I add the lib dir to @INC with command

use lib '~/perl5/lib';

But, I get the error

Can't locate Excel/Writer/XLSX.pm in @INC (@INC contains: ~/perl5/lib ...

I could not figure out the exact dir location, so I tried

use lib '~/perl5/lib/'; use lib '~/perl5/lib/perl5'; use lib '~/perl5/lib/perl5/';

Any help in pointing out the mistake is much appreciated.

Many thanks

Replies are listed 'Best First'.
Re: Load module from local dir
by Corion (Patriarch) on Sep 24, 2018 at 18:11 UTC

    I don't think that Perl will expand ~ to mean /home/anonymous_monk/, so you will have to do this expansion yourself:

    use lib '/home/anonymous_monk/perl5/lib/perl5';

    Alternatively see perlrun on how to set up @INC from the commandline:

    export PERL5LIB=~/perl5/lib/perl5

    Also, see the local::lib documentation on how to really set up local::lib. There are some steps you need to perform after installing it to get things set up.

Re: Load module from local dir
by Haarg (Priest) on Sep 25, 2018 at 11:50 UTC

    local::lib has special support for ~ paths. If you want to use the same paths with lib, you'll want to use $ENV{HOME}.

    Also, while the "base" directory used by local::lib is ~/perl5, that isn't the include path for libraries. It includes other directories like bin and man. The actual library path is in the lib/perl5 subdirectory. These paths are not entirely determined by local::lib itself, but also based on options given to ExtUtils::MakeMaker and Module::Build.
    use lib $ENV{HOME}.'/perl5/lib/perl5';
Re: Load module from local dir
by cavac (Parson) on Sep 25, 2018 at 09:47 UTC

    BEGIN and @INC are your friend here:

    /usr/bin/env perl use strict; use warnings; BEGIN { unshift @INC, '~/perl5/lib/perl5'; } use Excel::Writer::XSLX;

    ...or even via a conditional '--debug' command line argument:

    /usr/bin/env perl use strict; use warnings; use Array::Contains; BEGIN { if(contains('--debug', \@ARGV)) { print("Development INC activated\n\n"); unshift @INC, '~/perl5/lib/perl5'; } } use Excel::Writer::XSLX;
    "For me, programming in Perl is like my cooking. The result may not always taste nice, but it's quick, painless and it get's food on the table."
      /usr/bin/env perl use strict; use warnings; BEGIN { unshift @INC, '~/perl5/lib/perl5'; } use Excel::Writer::XSLX;
      /usr/bin/env perl use strict; use warnings; use Array::Contains; BEGIN { if(contains('--debug', \@ARGV)) { print("Development INC activated\n\n"); unshift @INC, '~/perl5/lib/perl5'; } } use Excel::Writer::XSLX;

      Did you try your examples? I don't think so.

      Both are missing a shebang (#!) in line 1 and would cause a syntax error. Plus, as shown in Load module from local dir, neither manipulating @INC nor use lib expand the tilde. unshift never should, and use lib doesn't, at least not in my Perl:

      /home/alex>cd /tmp/ /tmp>echo 'package Foo;1;' > ~/Foo.pm /tmp>perl -E 'use Foo; say "ok"' Can't locate Foo.pm in @INC (you may need to install the Foo module) ( +@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib +64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /u +sr/share/perl5 .) at -e line 1. BEGIN failed--compilation aborted at -e line 1. /tmp>perl -E 'use lib "~"; use Foo; say "ok"' Can't locate Foo.pm in @INC (you may need to install the Foo module) ( +@INC contains: ~ /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/l +ib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 +/usr/share/perl5 .) at -e line 1. BEGIN failed--compilation aborted at -e line 1. /tmp>perl -E 'use lib "~/."; use Foo; say "ok"' Can't locate Foo.pm in @INC (you may need to install the Foo module) ( +@INC contains: ~/. /usr/local/lib64/perl5 /usr/local/share/perl5 /usr +/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl +5 /usr/share/perl5 .) at -e line 1. BEGIN failed--compilation aborted at -e line 1. /tmp>perl -E 'use lib $ENV{"HOME"}; use Foo; say "ok"' ok /tmp>perl -v This is perl 5, version 22, subversion 2 (v5.22.2) built for x86_64-li +nux-thread-multi Copyright 1987-2015, Larry Wall Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using "man perl" or "perldoc perl". If you have access to + the Internet, point your browser at http://www.perl.org/, the Perl Home Pa +ge. /tmp>

      And by the way:

      Saying

      use lib LIST;

      is almost the same as saying

      BEGIN { unshift(@INC, LIST) }
      (from lib)

      Except that newer versions of lib do some additional fancy stuff with architecture-specific directories:

      For each directory in LIST (called $dir here) the lib module also checks to see if a directory called $dir/$archname/auto exists. If so the $dir/$archname directory is assumed to be a corresponding architecture specific directory and is added to @INC in front of $dir. lib.pm also checks if directories called $dir/$version and $dir/$version/$archname exist and adds these directories to @INC.

      Also, if can be used to conditionally load other modules, including lib:

      /tmp>perl -E 'use if -f(qq[$ENV{"HOME"}/Foo.pm]), lib => $ENV{"HOME"}; + use Foo; say "ok"' ok /tmp>

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

        Damn! I know i shouldn't just copy&paste from my source repo without testing. Sorry!

        "For me, programming in Perl is like my cooking. The result may not always taste nice, but it's quick, painless and it get's food on the table."
Re: Load module from local dir
by ikegami (Patriarch) on Sep 28, 2018 at 17:46 UTC

    Rather than placing

    use lib "$ENV{HOME}/perl5/lib/perl5";

    in all of your Perl programs, consider placing

    export PERL5LIB=~/perl5/lib/perl5

    in your login script.