假设我有三个perl模块,如下所示:
Test.pm
package Test;
use strict;
use warnings;
use Check;
our $data = Check->getX;
1;
Initialize.pm
package Initialize;
use Check;
use Test;
Check->setX(10);
our $t = $Test::data;
print $t;
1;
Check.pm
package Check;
my $x = 12;
sub setX {
my ($self,$value) = @_;
$x = $value;
}
sub getX
{
return $x;
}
1;
现在,当我运行Initialize.pm时,我将Check.pm中的$ x初始化为10,并将$ x分配给Test.pm中的$ data。但是分配给$ data的实际值是12,这是Check.pm中给出的初始值。
那么,在perl中初始化全局变量的时间是什么时候?如何强制我在Initialize.pm中设置的新值到x是加载到$ data的内容?
现在,如果我替换语句,请在Initalize.pm中使用Test并使用require Test;并在此require语句之前移动语句Check-> setX(10),然后将$ data正确初始化为新值10. 在这种情况下会发生什么不同?
答案 0 :(得分:1)
Perl在执行文件中的任何其他内容之前执行use语句。 所以执行顺序是:
use Check;
$x = 12;
use Test;
use Check;
- 这只会在文件已执行时导入$data = Check->getX();
Check->setX(10);
如果用use
替换require
,则指令与其余指令同时进行评估,如果在要求之前移动Check->setX(10);
,则在获取之前对其进行评估在测试中
答案 1 :(得分:1)
通常,模块很少或没有可执行代码。面向对象的模块只定义了对象方法,有时还定义了一些类数据。
当use Test
编译并执行整个Test.pm
时,此时设置$data
的值。
之后发生对setX
的调用,但为时已晚,无法影响$data
的排名。
正如我在评论中所说,您的代码具有非常奇怪的结构,并且模块根本不应该彼此依赖于时间。您应该从模块中删除所有可执行语句,但强制您的代码执行您想要的操作
use strict;
use warnings;
use Check;
BEGIN {
Check->setX(10);
}
use Test;
our $t = $Test::data;
print $t;
但不要这样做!