3

我在我的脚本中使用自定义模块并且必须将它们存储在 Perllib目录之外。因此,在 Perl 脚本 ( *.pl) 中,我使用以下块将它们包含在@INC

BEGIN {
  use FindBin qw($Bin);
  push @INC, "$Bin/../ModulesFolder1";
  push @INC, "$Bin/../ModulesFolder2";
}

但是我还必须在我的其他 Perl 模块 ( *.pm) 中使用模块,据我所知FindBin,它只适用于脚本。所以我将该块更改为:

BEGIN {
  push @INC, catdir( dirname( $INC{'ThisModule.pm'} ), qw( .. ModulesFolder1 ) );
  push @INC, catdir( dirname( $INC{'ThisModule.pm'} ), qw( .. ModulesFolder2 ) );
}

它有效,但有一个小问题。我在 Eclipse 中使用 EPIC 插件进行编码,并且“如果您在 BEGIN 块中有导致编译器过早中止的内容,它不会向 EPIC 报告语法错误”,因此我在模块中放松了 Perl 语法检查。
因此,使用FindBin(在脚本中)我不必catdir在块中使用任何函数(如 )BEGIN{},并且以下代码的语法检查正确进行。此外,我不想更改任何环境变量(如PERL5LIB),这样我就可以在同事的机器上使用脚本而无需任何额外的准备。

在其他模块中使用自定义 Perl 模块并且不同时干扰 EPIC 语法检查的正确方法是什么?或者我什至应该以完全其他方式包含模块?

4

4 回答 4

4

我强烈反对@INC在模块中进行修改。它会引起各种头痛。让脚本(甚至通过PERL5LIB环境变量调用进程)@INC正确设置。

script.pl

use FindBin qw( $RealBin );
use lib
   "$RealBin/../ModulesFolder1",
   "$RealBin/../ModulesFolder2";

use ModuleInFolder1;

ModuleInFolder1.pm

use ModuleInFolder2;  # Works fine.

对于 EPIC,请执行以下操作:

  1. 右键单击项目。
  2. 特性
  3. Perl 包含路径
  4. ${project_loc}/ModulesFolder1, 添加到列表中
  5. ${project_loc}/ModulesFolder2, 添加到列表中

(我的字面意思是 14 个字符${project_loc}。这对 EPIC 来说意义重大。即使您移动项目,它也会继续工作。)


PS -$RealBin比它更好,$Bin因为它允许您使用符号链接到您的脚本。

PS -__FILE__比 更合适$INC{'ThisModule.pm'}

于 2012-07-27T17:56:25.190 回答
1

不确定 Eclipse,但您可以使用use lib(可能无法正常工作,它会@INC在编译时更改)或将环境变量设置PERL5LIB为指向您的库文件夹。

于 2012-07-27T11:56:05.550 回答
1

设置PERL5LIB环境变量。每次使用或要求时,Perl 都会检查其中列出的所有目录。

或者,将所有必要的自定义模块放在脚本的目录下,这样您就可以在use lib. 它还允许您通过从顶级目录递归打包来快速制作捆绑包以将所有内容传输到另一台 PC。

于 2012-07-27T11:56:32.103 回答
0

另一个解决方案(来自我的同事) - 在模块中进行更改:

sub path_to_current_module() {
  my $package_name = __PACKAGE__ .'.pm';
  $package_name =~ s#::#/#g;

  for my $path ( @INC ) {
    # print "\$path == '$path'\n";
    if ( -e catfile( $path, $package_name ) ) {
      return $path;
    }
  }

  confess;
}

BEGIN {
  my $path_to_current_module = path_to_current_module();
  push @INC, catdir( $path_to_current_module, qw( .. ModulesFolder1 ) );
  push @INC, catdir( $path_to_current_module, qw( .. ModulesFolder2 ) );
}

似乎旧方法(在问题中描述)Perl 无法在其中找到当前模块名称@INC- 这就是为什么在块perl -c内被错误中断的原因。BEGIN所描述的 sub 帮助它确定当前模块的真实路径。此外,它不依赖于当前文件名,可以复制到另一个模块。

于 2012-07-30T16:48:24.183 回答