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

时间:2013-07-15 18:20:04

标签: 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");
} 

1 个答案:

答案 0 :(得分: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操作),就像它被评估(source)一样。

BEGIN + @INC更改相比,此方法有许多好处:

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

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

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


要解决“MyIncPathMaintenance.pm去哪里?”的问题,这取决于您的环境。您可以在此处详细讨论@INC的构建方式:How is Perl's @INC constructed? (aka What are all the ways of affecting where Perl modules are searched for?)

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