如何在perl脚本中包含BEGIN部分

eri*_*ung 3 perl

我有一堆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");
} 
Run Code Online (Sandbox Code Playgroud)

DVK*_*DVK 8

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

package MyIncPathMaintenance;
push @INC, "something_bvaluable";
1;
Run Code Online (Sandbox Code Playgroud)

然后,您的所有脚本只需要:

use MyIncPathMaintenance;

作为他们在shebang和.之后的第一线 use strict

这是有效的,因为use XYZ相当于BEGIN { require XYZ; XYZ->import() }(来源); 而那require将执行模块的代码(包括你的@INC操作),就好像它是evaled()一样.

这种方法比BEGIN + @INC变化有许多好处:

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

  • 它封装了一些有些高级的功能,这些功能对于那些不知道自己在做什么并可能会破坏它的初级开发人员来说可能有点危险("嘿,我只是将我的主目录添加到这条路径中,这样我就可以运行我的ad-hoc库版本没有核心审查/测试/发布SDLC").

  • 它允许脚本中更多花哨的逻辑(在我们的例子中,模块自动为BETA脚本预先设置BETA库路径).


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

包括Perl解释器的默认@INC值以及如何通过环境变量对其进行影响.