【问题标题】:How to include BEGIN section in a perl script如何在 perl 脚本中包含 BEGIN 部​​分
【发布时间】:2013-07-15 18:20:04
【问题描述】:

我有一堆 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");
} 

【问题讨论】:

  • 您可能会考虑将PERL5LIB 环境变量设置为指向您的包含路径 - 用: 分隔。然后,您无需将其添加到所有脚本中,而是添加到脚本运行的环境中。
  • 或者考虑使用某种包管理解决方案(CPAN,或操作系统的包管理器)以稳健且可维护的方式将您的库放入解释器的默认位置。

标签: perl


【解决方案1】:

是的。您可以简单地将该代码(将进入 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 的情况下运行我的 ad-hoc 库版本”)。

  • 它在脚本中允许更多花哨的逻辑(在我们的例子中,模块自动为 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 是什么以及如何通过环境变量影响它。

【讨论】:

  • 那么问题可能是:把所有脚本都找到的 MyIncPathMainenance.pm 放在哪里?
  • @KarstenS。 - 这完全取决于您的环境。我们有标准目录,所有服务器的 Perl 编译入 \@INC 都可以看到我工作的位置。如果您运行perl -V,您将看到您的默认@INC。有关如何构建 \@INC 的更多详细信息(包括您可以用来影响它的环境变量),请参见此处:stackoverflow.com/questions/2526804/…
  • 这只是将问题从向每个程序添加BEGIN 块更改为向每个程序添加use 语句。虽然它稍微好一点,因为任何更常见的需求都可以添加到新模块中。
  • @Borodin - 它也更易于维护(如果路径发生变化,您不必更改所有脚本)。它还隐藏了 \@INC 魔法,不让那些不应该使用它的人发现。
  • In "push @INC, "something_bvaluable"; "something_bvaluable" 是模块的绝对路径吗?我们的脚本会在本地测试,然后移动到服务器。绝对路径可能不同本地机器和服务器上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
  • 2013-04-04
  • 1970-01-01
  • 2019-07-30
相关资源
最近更新 更多