Reputation: 879
I am reading documentation about use
. It is the same as
BEGIN{ require Namespace::NameOfModule; }
And the perl interpreter loads the module and translate the double colon ::
to system path's separator (UNIX /
and WINDOWS \\
, if I remember correctly). I just wondered, If I am able to load module from root. Because in that case, for example module DateTime.pm
in dir /home/nickname/dir
. It would be (according to double colons rule) ::home::nickname::dir
, which is wrong (like it should even look like terrible package path). So how - if even - is possible to load a module from root dir? And Does the path starts from current dir by default? (That is from dir where is the perl script located in), or only from @INC
dirs?
Upvotes: 0
Views: 386
Reputation: 386676
Even if you could load the module like that, you'd have numerous other problems.
package
directive would have to be package ::home::nickname::dir::SomeModule;
for import
to be found.::home::nickname::dir::SomeModule->some_method
to call a static method.::home::nickname::dir::SomeModule::some_sub
to call a sub.That's obviously the wrong approach.
For modules installed in a position relative to a script, use the following in the script to tell perl
where to look:
use FindBin qw( $RealBin );
use lib "$RealBin/../lib"; # Or whatever.
For modules installed for any script to use, use the following environment variable:
export PERL5LIB="$HOME/dir" # Or whatever.
Upvotes: 2
Reputation: 9231
The module namespace is relative to @INC
directories only. These are by default set up according to where Perl was installed, with privlib (core modules installed with Perl), sitelib (modules installed by a CPAN client), and vendorlib (modules installed by a vendor package manager), and architecture-specific versions of each of these. Additional @INC
directories may be added by local::lib, and before Perl 5.26 @INC
also included .
(the current working directory), but this was a bad idea.
When you invoke use
or require
on a bareword package name, it does the translation you described (convert ::
to path separator and append .pm
), and then appends it to each directory in @INC
until it finds a file. (It also checks for .pmc
but this is rarely relevant.) The package statement inside the file is expected to match the module path used to look it up for the import component of use
.
You can modify @INC
manually, but it is best to do it with one of the following mechanisms, so that architecture-specific and version-specific subdirectories will be respected if present.
use lib '/path/to/lib';
perl -I/path/to/lib ...
env PERL5LIB=/path/to/lib perl ...
These options should only be used to insert absolute paths into @INC
, since relative paths will have the same vulnerability as .
used to, in that they may mean something different when the current directory is changed. To add a path relative to the script wherever it may be, lib::relative can be installed to simplify the process, or its documentation describes equivalent functionality using core modules.
use lib::relative '../lib';
Once you have added your custom location(s) to @INC
, that directory will be searched first for any further use
calls.
use Foo::Bar; # now checks /path/to/lib/Foo/Bar.pm first
# which should contain package Foo::Bar
Upvotes: 5