4

Does Perl look in . (the current directory) for modules?

I can't directly install a module and I think I could copy it into the local directory. Is this true?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Leo Izen
  • 4,165
  • 7
  • 37
  • 56

6 Answers6

14

perl -V will print out various properties about your Perl installation, including the default @INC. You should notice a . in there: yes, the current working directory is searched for modules by default.

(If not, you can use environment variables PERL5LIB or PERLLIB, or -I on the command line, or add a sitecustomize.pl to perl -V:sitelib.)

ephemient
  • 198,619
  • 38
  • 280
  • 391
  • 4
    Installing stuff into dot, the process’s current working directory, doesn’t really work and shouldn’t be relied upon. It is nothing at all like `$FindBin::Bin`! – tchrist Jan 16 '11 at 04:01
  • @tchrist: What exactly doesn't work? I have a feeling I'm missing subtleties here... – Cameron Jan 16 '11 at 04:03
  • 6
    @Cameron: Relying on the **process’s** cwd() is very dodgy; it means that you have to be in a particular directory to run a particular program, which is nuts. If you want to put modules in the same starting directory as the main script itself, you need `use FindBin; use lib $FindBin::Bin;` instead. You do not ever want to risk relying on the vicissitudes of where somebody last cd’d to when you want to load in essential components of your own program. – tchrist Jan 16 '11 at 04:10
  • @tchrist: +1, good point! I understand what you meant now, thanks for clearing that up – Cameron Jan 16 '11 at 04:35
6

In response to Cameron and tchrist's discussion in the comments to ephemient's answer.

You may use this snippet to use modules in the same directory as the script, even if the script is executed while in another directory.

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

It should work in all cases and on all OSes. (Source: http://use.perl.org/~Aristotle/journal/33995)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Joel Berger
  • 20,180
  • 5
  • 49
  • 104
  • Is there some particular reason to reïmplement the standard `FindBin` module? That module does do a bit more, like understanding if the script is a symlink and resolving that through reading the link contents first. – tchrist Jan 16 '11 at 13:59
  • I found the link that I reference a while back while trying to answer this same question for myself. In that link they discuss limitations of FindBin that I admit I am not sure I understand, they then settle on this snippet as a general application tool. I have used it several times since with good result so I guess I never looked back. Were their fears justified or should I switch to FindBin in the future? – Joel Berger Jan 16 '11 at 14:16
  • I also see a new CPAN module called scriptname (http://search.cpan.org/perldoc?scriptname) can I have your thoughts on that? – Joel Berger Jan 16 '11 at 14:32
  • The link seems to be broken (timed out - no response on sub domain `use.perl.org`, while `perl.org` worked). – Peter Mortensen Dec 12 '20 at 08:44
5

Lately there has been some reason to not rely on . being in @INC more than usual, namely that this default behavior is scheduled to be removed in Perl 5.26. See the development release notes here: https://metacpan.org/pod/release/EXODIST/perl-5.25.7/pod/perldelta.pod#and-INC

It is generally known that this is being done to address vulnerabilities that were noticed in some applications as a result of this behavior. The CVE(s) have not been released publicly (yet).

Joel Berger
  • 20,180
  • 5
  • 49
  • 104
  • This sounds like a good idea for security. The reason I wanted to do this six years ago (wow!) was my website used Yahoo Web Hosting and it wasn't really secure: mod_perl had security hole (or the config file was poorly written) where it would give me read/execute permissions on various things it shouldn't have. There was a Perl module I wanted to install that I couldn't because I didn't have write permissions to /usr, but the idea was to just dump it in ./ and load it through my execute permissions. The module ended up being unimportant (IO::Compress or something) but this should be fixed. – Leo Izen Dec 19 '16 at 09:25
  • It actually gave me write permissions on stuff it shouldn't have because of a misconfigured root node. The server was shared with some family members and I was supposed to have permissions on the /leo/ directory, but it wasn't mounted for me as /. So I could mess with everyone else's files. I only used it to fix bugs in their scripts for them in my free time, but it was still pretty bad. – Leo Izen Dec 19 '16 at 09:29
  • Time for an update (***without*** "Edit:", "Update", or similar)? – Peter Mortensen Dec 12 '20 at 08:47
1

Perl searches directories in the @INC array when searching for modules.

Please refer to the following Stack Overflow question on how that array is constructed (this would tell you how your current or home directory can be added):

How is Perl's @INC constructed? (aka What are all the ways of affecting where Perl modules are searched for?)

Please refer to the following Stack Overflow question on how Perl finds the actual file for the module:

How does a Perl program know where to find the file containing Perl module it uses?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
DVK
  • 126,886
  • 32
  • 213
  • 327
  • As noted in tchrist's answer, using **current** directory (e.g. `.`) is a Bad Idea in general. – DVK Jan 16 '11 at 13:56
0

I think it most likely will by default, as indicated in this post. If your implementation does not do so, the syntax referenced in the initial question on that post will allow you to reference the module you need.

mlschechter
  • 994
  • 5
  • 8
0

When you unpack the module’s tarball directory, build its Makefile with an optional library argument with the name of whatever personal directory you want the module contents placed in:

$ perl Makefile.PL LIB=~/perllibs

Then make sure you have your ~/perllibs directory included in your $PERL5LIB envariable.

tchrist
  • 78,834
  • 30
  • 123
  • 180