Perl中的BEGIN块

Ale*_*lex 1 perl

在Internet上搜索,我知道BEGIN块将在编译阶段进行评估和执行.但是@INC或其他变量可以继承吗?

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

|-- alexpackages
|   |-- alex1.pm
|   `-- alex2.pm
|-- foo.pl
`-- main.pl
Run Code Online (Sandbox Code Playgroud)

对于每个文件:

cat alexpackages/alex1.pm

package alex1;

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

1;
Run Code Online (Sandbox Code Playgroud)

猫alexpackages/alex2.pm

package alex2;

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

1;
Run Code Online (Sandbox Code Playgroud)

猫foo.pl

alex1::foo();
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

我可以如何使环境变量进行以下系统调用?

Bor*_*din 5

流程开始system 继承调用进程的环境变量,但@INC仅仅是一个全球性的Perl变量,而不是一个系统环境变量.它在Perl程序之外是不可见的.

关于代码的几点说明

  • 包名,是全局,予以资本化,所以你的包应该是Alex1Alex2在文件alexpackages/Alex1.pmalexpackages/Alex2.pm

  • 最好使用libpragma来操作@INC,所以

    use lib '~/programs/perl/alexpackages'
    
    Run Code Online (Sandbox Code Playgroud)

    是最好的.并且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();
Run Code Online (Sandbox Code Playgroud)

〜/程序/ 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;
Run Code Online (Sandbox Code Playgroud)