7

If I have a .pm file, is there a way I can use it, without placing it on my @INC path? I think that would be clearer in my particular use case - clearer than using relative paths or adding this directory to @INC.

Edit: Clarification:

I was hoping to avoid the necessity to iterate through every item in @INC, and instead specify directly which file I am interested in. For example, in Node.JS, require('something') will search the list of paths, but require('/specific/something') will go directly where I tell it to.

In Perl, I am not certain that this is the same functionality found in require, but it seems to work.

However, use statements require barewords. That has left me a little stumped on how to enter an absolute path.

divibisan
  • 11,659
  • 11
  • 40
  • 58
700 Software
  • 85,281
  • 83
  • 234
  • 341
  • `use lib` statement before `use module` will be correct for your case. But why can't you use `require`. It more suits for your problem. Also you can `SetEnv PERL5LIB` environment variable in apache conf to apply that directory for whole project or application. –  Feb 14 '13 at 10:56
  • I need to require a `.pm` file. I have not tried, but it doesn't seem like it would work right. I usually call functions in the module with syntax like `CGI::ReadParse();` or `use CGI ':cgi';`. I do not know how I could do that with `require` for a `.pm` file, but if I could do that with `require`, it would indeed solve my problem. – 700 Software Feb 14 '13 at 14:28
  • It works. Try like this `require "Newmodule.pm";` and then call `Newmodule::subname();`. It executes fine. –  Feb 14 '13 at 14:50

5 Answers5

7

You can use this :

use lib '/path/to/Perl_module_dir'; # can be both relative or absolute
use my_own_lib;

You can modify @INC by yourself (temporarily, no fear, that's what use lib does too) :

BEGIN{ @INC = ( '/path/to/Perl_module_dir', @INC ); } # relative or absolute too
use my_own_lib;
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
  • The latter is very similar to what `use lib` does, except that that uses `unshift` instead of `pop` to make sure that your own modules are picked up before anything else of the same name. – Borodin Feb 13 '13 at 13:47
  • POST edited accordingly to push at the beginning of the array. – Gilles Quénot Feb 13 '13 at 13:53
  • 2
    putting a module in the same directory as your program only works fine if that is your working directory. `. != dirname ` by default... – pavel Feb 13 '13 at 14:05
  • 1
    and only works when . is in @INC (not true in taint mode; not true for distros that omit it to be more secure) – ysth Feb 13 '13 at 17:25
  • That last comment is false. Perl does not look in the script's directory for modules. It *usually* looks in `.`, but not always, and `.` is *often* the script's directory, but far from always. – ikegami Feb 13 '13 at 20:55
  • `use lib` also adds arch directories within the specified directories to `@INC`. – ikegami Feb 13 '13 at 20:56
  • The code you claim modifies `@INC` temporarily does not modify it any more temporarily than `use lib`. – ikegami Feb 13 '13 at 20:56
4

As per discussion in comments, I would suggest using require itself. Like below,

require "pathto/module/Newmodule.pm";

Newmodule::firstSub();

Also you can use other options as below

  • use lib 'pathto/module'; This line needs to be added to every file you want to use the module in.

use lib 'pathto/module';
use Newmodule;

  • using PERL5LIB environment variable. Set this on command line using export or add this to ~/.bashrc so that with every login it will be added to your @INC. Remember PERL5LIB adds directory before all @INC directories. So it will be used first. Also you can set it in apache httpd.conf using

    SetEnv PERL5LIB /fullpath/to/module
    
  • Or set it in BEGIN block.

1

Generally speaking, set the PERL5LIB environment var.

export PERL5LIB=/home/ikegami/perl/lib

If the module to find is intended to be installed in a directory relative to the script, use the following:

use FindBin qw( $RealBin );
use lib $RealBin;
  # or
use lib "$RealBin/lib";
  # or
use lib "$RealBin/../lib";

This will correctly handle symbolic links to the script.

$ mkdir t

$ cat >t/a.pl
use FindBin qw( $RealBin );
use lib $RealBin;
use Module;

$ cat >t/Module.pm
package Module;
print "Module loaded\n";
1;

$ ln -s t/a.pl

$ perl a.pl
Module loaded
ikegami
  • 367,544
  • 15
  • 269
  • 518
0

You can use the Module::Load module

use Module::Load;
load 'path/to/module.pm';
user2050283
  • 562
  • 1
  • 4
  • 9
  • There's no indication he wants to load the module at runtime, so you'd wrap the module in a `BEGIN`. It also doesn't provide a means of importing symbols, so you'd have to add a call to `import` in the BEGIN block too. Altogether a poor solution for what the OP wants to do. – ikegami Feb 13 '13 at 20:58
0

FindBin::libs does the trick:

# search up $FindBin::Bin looking for ./lib directories
# and "use lib" them.

use FindBin::libs;
creaktive
  • 5,193
  • 2
  • 18
  • 32
  • It uses FindBin::libs uses $FindBin:Bin instead of $FindBin:RealBin, so it doesn't work when using a symlink to the script :( – ikegami Feb 13 '13 at 20:45