4

假设我们是 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
  • @INCBEGIN添加到我们的脚本部分中手动添加我们的路径use lib '/home/user/GreatScript';,但它看起来很糟糕。如果我们将脚本移动到其他目录怎么办?
  • 或者使用FindBinmodule 找到我们当前的目录,use lib "$FindBin::Bin";在.
  • 或者使用 __FILE__ (或 $0)变量并使用模块中的abs_path方法从中提取路径。Cwd看起来像另一辆自行车?
  • 或者一些忘记或丢失(我错过了什么吗?)

为什么这种明显且常规的操作需要大量工作?如果我有一个脚本,这很容易......但是为什么我需要为我的所有脚本编写这几行额外的代码呢?而且它不会 100% 起作用!为什么 perl 默认不添加当前脚本目录@INC,就像使用“.”一样?

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

4

3 回答 3

5

或者一些忘记或丢失(我错过了什么吗?)

另一种选择:不要将您的模块与您的脚本一起保存。该模块是独立的,因为它是可重复使用的,所以将它放在一个库文件夹中。这可以是任何东西,从用于个人项目的本地库,包括use lib(并且可能引用您为项目设置的环境变量),到将模块制作成 CPAN 库,并让cpan管理它的去向。你决定做什么取决于你的代码的可重用性,而不是脚本如何使用它。

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

在事物的计划中,这不是很多工作。您期望在文件系统中组合在一起的文件应该由 Perl 在语言级别自动使用来解析requireoruse语句是不正确的。不是不可能,也不是你的期望不合理,只是 Perl 不是这样实现的。事后改变它可能会影响现有项目的工作量,并且可能会引起争议——因此不太可能改变。

于 2013-11-01T09:53:20.993 回答
4

如果您的用例是:“我想要一个脚本来访问相同或相对目录中的其他模块或其他资源,并且我不想安装所有东西”,那么 FindBin 是一个完美的解决方案。手册页中提到的限制只发生在像 mod_perl 这样的持久环境中,但在这里我会提出不同的解决方案(例如,仅在 httpd.conf 中使用 FindBin,而不是在脚本/模块中)。

(/me 是 FindBin 的重度用户,我也是 FindBin 手册页的 KNOWN ISSUES 部分的一半的作者)

于 2013-11-01T13:03:19.337 回答
2

这是为了知道您想使用哪个模块。当您按照您所说的移动到另一个目录时,perl 会在“。”中查找。目录所以如果运行:

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

如果 MyModule.pm in '/' perl 会找到它并将在myscrpit.pl. 现在,当 Perl 在 @INC 中查找模块时,您必须留意 @INC 中的目录。

总结:明显和规律的操作是需要防止使用错误的同名模块。

于 2013-11-01T09:46:34.060 回答