How do I “use” a Perl module in a directory not in @INC?

偶尔善良 提交于 2019-11-26 06:29:35

问题


I have a module in the parent directory of my script and I would like to \'use\' it.

If I do

use \'../Foo.pm\';

I get syntax errors.

I tried to do:

push @INC, \'..\';
use EPMS;

and .. apparently doesn\'t show up in @INC

I\'m going crazy! What\'s wrong here?


回答1:


use takes place at compile-time, so this would work:

BEGIN {push @INC, '..'}
use EPMS;

But the better solution is to use lib, which is a nicer way of writing the above:

use lib '..';
use EPMS;

In case you are running from a different directory, though, the use of FindBin is recommended:

use FindBin;                     # locate this script
use lib "$FindBin::RealBin/..";  # use the parent directory
use EPMS;



回答2:


There are several ways you can modify @INC.

  • set PERL5LIB, as documented in perlrun

  • use the -I switch on the command line, also documented in perlrun. You can also apply this automatically with PERL5OPT, but just use PERL5LIB if you are going to do that.

  • use lib inside your program, although this is fragile since another person on a different machine might have it in a different directory.

  • Manually modify @INC, making sure you do that at compile time if you want to pull in a module with use. That's too much work though.




回答3:


Personally I prefer to keep my modules (those that I write for myself or for systems I can control) in a certain directory, and also to place them in a subdirectory. As in:

/www/modules/MyMods/Foo.pm
/www/modules/MyMods/Bar.pm

And then where I use them:

use lib qw(/www/modules);
use MyMods::Foo;
use MyMods::Bar;

As an aside.. when it comes to pushing, I prefer the fat-arrow comma:

push @array => $pushee;

But that's just a matter of preference.




回答4:


'use lib' is the answer, as @ephemient mentioned earlier. One other option is to use require/import instead of use. It means the module wouldn't be loaded at compile time, but instead in runtime.

That will allow you to modify @INC as you tried there, or you could pass require a path to the file instead of the module name. From 'perldoc -f require':

If EXPR is a bareword, the require assumes a ".pm" extension and replaces "::" with "/" in the filename for you, to make it easy to load standard modules. This form of loading of modules does not risk altering your namespace.




回答5:


You have to have the push processed before the use is -- and use is processed early. So, you'll need a BEGIN { push @INC, ".."; } to have a chance, I believe.




回答6:


As reported by "perldoc -f use":

It is exactly equivalent to
BEGIN { require Module; import Module LIST; }
except that Module must be a bareword.

Putting that another way, "use" is equivalent to:

  • running at compile time,
  • converting the package name to a file name,
  • require-ing that file name, and
  • import-ing that package.

So, instead of calling use, you can call require and import inside a BEGIN block:

BEGIN {
  require '../EPMS.pm';
  EPMS->import();
}

And of course, if your module don't actually do any symbol exporting or other initialization when you call import, you can leave that line out:

BEGIN {
  require '../EPMS.pm';
}


来源:https://stackoverflow.com/questions/185114/how-do-i-use-a-perl-module-in-a-directory-not-in-inc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!