简体   繁体   English

Perl中的BEGIN块

[英]BEGIN blocks in Perl

Searching the Internet, I get that the BEGIN block will get evaluated and executed in the compile phase. 搜索Internet,我发现BEGIN块将在编译阶段进行评估和执行。 But can the @INC or other variables be inherited? 但是@INC或其他变量可以继承吗?

Below is what I wrote for testing. 以下是我为测试编写的内容。 The directory structure is as: 目录结构为:

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

For each file: 对于每个文件:

cat alexpackages/alex1.pm 猫alexpackages / alex1.pm

package alex1;

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

1;

cat alexpackages/alex2.pm 猫alexpackages / alex2.pm

package alex2;

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

1;

cat foo.pl 猫foo.pl

alex1::foo();

cat main.pl 猫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

Just as what my program tells that the @INC does not work for a new system call. 就像我的程序告诉@INC不适用于新的系统调用一样。 It seems to me that system call will not inherit the system environment. 在我看来,系统调用不会继承系统环境。 Am I right? 我对吗?

And can how I make the environment variables to the following system call? 以及如何将环境变量设置为以下系统调用?

Processes started with system will inherit the environment variables from the calling process, but @INC is just a global Perl variable, not a system environment variable. 流程开始system 继承调用进程的环境变量,但@INC仅仅是一个全球性的Perl变量,而不是一个系统环境变量。 It is not visible outside the Perl program. 在Perl程序外部不可见。

A couple of notes on your code 关于代码的一些注意事项

  • Package names, being globals, should be capitalised, so your packages should be Alex1 and Alex2 , in files alexpackages/Alex1.pm and alexpackages/Alex2.pm 包名,是全局,予以资本化,所以你的包应该是Alex1Alex2 ,在文件alexpackages/Alex1.pmalexpackages/Alex2.pm

  • It is best to use the lib pragma to manipulate @INC , so 最好使用lib编译指示来操作@INC ,因此

     use lib '~/programs/perl/alexpackages' 

    is best. 是最好的。 And a use statement creates an implicit BEGIN block, so that is also unnecessary. 并且一条use语句创建一个隐式的BEGIN块,因此这也是不必要的。

  • It is wrong to use prototypes on Perl subroutines, so sub foo() should be just sub foo 在Perl子例程上使用原型是错误的,因此sub foo()应该只是sub foo

  • You may prefer to use Exporter to copy the symbols of a package into the calling code. 您可能更喜欢使用Exporter将包的符号复制到调用代码中。 That way you don't have to fully-qualify your subroutine name when you call it, like foo() instead of Alex1::foo() 这样,您不必在调用子例程名称时就完全限定其名称,例如foo()而不是Alex1::foo()

The code would look like this 代码看起来像这样

main.pl main.pl

use strict;
use warnings;

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

use Alex1;

foo();

~/programs/perl/alexpackages/Alex1.pm 〜/ programs / 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;

There are many ways to specify library search directories both from within a Perl script or the command line. 有很多方法可以从Perl脚本或命令行中指定库搜索目录。 Here are two things you could do to make another directory available to the Perl script you invoke with system : 您可以执行以下两项操作来使另一个目录可用于您使用system调用的Perl脚本:

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


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

Both PERL5LIB and the -I switch are documented in perlrun . PERL5LIB中记录了perlrun-I开关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM