在互联网上搜索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不能用于新的系统调用一样。在我看来,系统调用不会继承系统环境。我是对的吗?
我可以如何将环境变量用于以下系统调用吗?
答案 0 :(得分:5)
以system
开始的进程将从调用进程继承环境变量,但@INC
只是一个全局Perl变量,而不是系统环境变量。它在Perl程序之外是不可见的。
关于代码的几点说明
包名称(全局变量)应该大写,因此您的包应该是Alex1
和Alex2
,文件alexpackages/Alex1.pm
和alexpackages/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
开关。