Perl中的BEGIN块

时间:2014-04-24 10:16:50

标签: perl

在互联网上搜索BEGIN块将在编译阶段得到评估和执行。但是@INC或其他变量可以继承吗?

以下是我为测试而写的内容。目录结构如下:

|-- alexpackages
|   |-- alex1.pm
|   `-- alex2.pm
|-- foo.pl
`-- main.pl

对于每个文件:

cat alexpackages / alex1.pm

package alex1;

sub foo()
{
    print "this is alex1::foo\n";
}

1;

cat alexpackages / alex2.pm

package alex2;

sub foo2()
{
    print "this is is alex2::foo2\n";
}

1;

cat foo.pl

alex1::foo();

cat main.pl

BEGIN
{
    push(@INC, '~/programs/perl/alexpackages');
}

use strict;
use warnings;

use alex1;
use alex2;

#alex1::foo();           # 1. This works good
system("perl foo.pl");   # 2. This fails

就像我的程序告诉@INC不能用于新的系统调用一样。在我看来,系统调用不会继承系统环境。我是对的吗?

我可以如何将环境变量用于以下系统调用吗?

2 个答案:

答案 0 :(得分:5)

system 开始的进程将从调用进程继承环境变量,但@INC只是一个全局Perl变量,而不是系统环境变量。它在Perl程序之外是不可见的。

关于代码的几点说明

  • 包名称(全局变量)应该大写,因此您的包应该是Alex1Alex2,文件alexpackages/Alex1.pmalexpackages/Alex2.pm

  • 最好使用lib pragma来操纵@INC,所以

    use lib '~/programs/perl/alexpackages'
    

    是最好的。并且use语句会创建一个隐式BEGIN块,因此这也是不必要的。

  • 在Perl子例程上使用原型是错误的,因此sub foo()应该只是sub foo

  • 您可能更喜欢使用Exporter将包的符号复制到调用代码中。这样,您在调用子例程名称时就不必完全限定子例程,例如foo()而不是Alex1::foo()

代码看起来像这样

<强> main.pl

use strict;
use warnings;

use lib '~/programs/perl/alexpackages';

use Alex1;

foo();

<强>〜/方案/的Perl / alexpackages / Alex1.pm

package Alex1;

use strict;
use warnings;

use base 'Exporter';

our @EXPORT = qw/ foo /;

sub foo {
  print "This is Alex1::foo\n";
}

1;

答案 1 :(得分:2)

有许多方法可以在Perl脚本或命令行中指定库搜索目录。您可以执行以下两项操作,使用system调用的Perl脚本可以使用另一个目录:

$ENV{PERL5LIB} = "~/programs/perl/alexpackages";
system("perl foo.pl");


system("perl -I~/programs/perl/alexpackages foo.pl");

perlrun中记录了PERL5LIB-I开关。