perl中的@INC出了什么问题?

时间:2013-11-01 09:20:40

标签: perl

让我们想象一下,我们是perl的新手并写了一些很棒的模块MyModule.pm。我们还写了一些很棒的脚本myscript.pl,需要使用这个模块。

use strict;
use warnings;
use MyModule;
etc...

现在我们将创建目录/home/user/GreatScript并将我们的文件放入其中。并尝试运行myscript.pl ...

cd /home/user/GreatScript
perl myscript.pl

大!现在转移到另一个目录......

cd /
perl /home/user/GreatScript/myscript.pl

获取有关@INC和路径列表的一些不太有用的错误。这是什么?现在经过一些谷歌搜索,我们知道@INC包含搜索模块的路径,这个错误意味着Perl无法找到MyModule.pm。

现在我们可以:

  • 添加系统PERL5LIB var的路径,它会将我们的路径添加到@INC的开头 将我们的模块安装到@INC
  • 中的一个目录
  • @INC部分中手动将我们的路径添加到BEGINuse lib '/home/user/GreatScript';添加到我们的脚本中,但它看起来很糟糕。如果我们将脚本移动到其他目录怎么办?
  • 或使用FindBin模块查找我们当前的目录,并在use lib "$FindBin::Bin";中使用此路径,但它不是100%有效,例如mod_perl或issues的一些错误...
  • 或者使用__FILE__(或$ 0)变量并使用abs_path模块中的Cwd方法从中提取路径。看起来像又一辆自行车?
  • 或者有些遗忘或遗失(我错过了什么?)

为什么这个明显且常规的操作需要大量的工作?如果我有一个脚本,那很简单......但是为什么我需要在我的所有脚本中编写这几行额外代码?它不会100%工作!为什么perl默认情况下不会将当前脚本目录添加到@INC,就像“。”一样?

PS:我正在寻找我的问题的答案,但只找到上面列表中的解决方案列表和其他一些解决方案。我希望这个问题重复......

3 个答案:

答案 0 :(得分:5)

  

或者有些遗忘或遗失(我错过了什么?)

另一种选择:不要将模块与脚本保持在一起。该模块是独立的,因为它是可重复使用的,因此将其放在库文件夹中。这可以是来自本地库的个人项目,包括use lib(可能引用您为项目设置的环境变量),将模块转换为CPAN库,并允许{{1}管理它去哪里。您决定做什么取决于代码的可重用性,超出脚本使用代码的方式。

  

为什么这种明显和常规的操作需要大量的工作?

事情方案中的工作并不多。您期望在文件系统中组合在一起的文件应由Perl在语言级别自动使用以解析cpanrequire语句。这并不是说不可能,或者你的期望是不合理的,只是Perl没有这样实现。事后改变可能会影响现有项目的工作量,并且可能会引起争议 - 所以不太可能改变。

答案 1 :(得分:4)

如果您的用例是:"我想要一个脚本来访问相同或相对目录中的其他模块或其他资源,我不想安装所有内容",然后FindBin是一个完美的解决方案联机帮助页中提到的限制只发生在mod_perl这样的持久环境中,但在这里我会提出不同的解决方案(例如,仅在httpd.conf中使用FindBin,而不是在脚本/模块中)。

(/我是一个沉重的FindBin用户,我也是FindBin手册页中一半已知问题部分的作者)

答案 2 :(得分:2)

需要知道您想要使用哪个模块。当你移动到另一个目录时,你说perl看起来'。'目录,所以如果运行:

cd /
perl /home/user/GreatScript/myscript.pl

如果'/'perl中的MyModule.pm将找到它并将在myscrpit.pl中使用。现在,当Perl在@INC中找到模块时,你必须关注@INC。

总结:需要明显和常规的操作来防止使用与您想要使用的名称相同的错误模块。