3

我有一堆 perl 脚本,每个脚本都需要有一个相同的 BEGIN 部​​分,这将我们开发的 perl 模块的路径添加到 @INC。因为它不是一个子,我不能简单地调用它。目前我在每个 perl 脚本中都包含这部分,这显然是一个令人头疼的维护。有没有更简单的方法来包含 BEGIN 部​​分?

BEGIN
{
     my $current_script_dir = File::Basename::dirname(File::Spec::Functions::rel2abs($0));

     # Assume that the root of all libraries is two levels up from the directory of the 
     # script being run.

     my $all_libs_root = File::Spec->canonpath("$current_script_dir/../..");

     # Make sure the path is absolute,      
     $all_libs_root = File::Spec->rel2abs($all_libs_root);

     unshift(@INC, "$all_libs_root");
} 
4

1 回答 1

8

是的。您可以简单地将该代码(将进入 BEGIN)放入一个新的 Perl 模块中。

package MyIncPathMaintenance;
push @INC, "something_bvaluable";
1;

然后,您的所有脚本只需要执行以下操作:

use MyIncPathMaintenance;

作为他们继 shebang 和use strict

这行得通,因为use XYZ相当于BEGIN { require XYZ; XYZ->import() }( source ); 而这require将执行模块的代码(包括您的@INC操作),就好像它是 eval-ed (source)。

这种方法比改变有很多好处BEGIN + @INC

  • 未来的可维护性要高得多。对路径的任何更改(或添加新路径)都封装在模块中,而不是在大量脚本中复制/粘贴

  • 它封装了一些高级功能,暴露给不知道自己在做什么并可能破坏它的初级开发人员可能有点危险(“嘿,我只需将我的主目录添加到此路径,以便我可以运行我的没有核心审查/测试/发布 SDLC 的临时库版本)。

  • 它允许脚本中的更多奇特逻辑(在我们的例子中,模块自动为 BETA 脚本添加 BETA 库路径)。


要解决“MyIncPathMaintenance.pm 去哪里?”的问题,这取决于您的环境。@INC您可以在此处找到有关如何构建的详细讨论: Perl 的 @INC 是如何构建的?(又名影响 Perl 模块搜索位置的所有方法是什么?)

包括您的 Perl 解释器的默认@INC值以及如何通过环境变量影响它。

于 2013-07-15T18:21:31.207 回答