1

假设我有三个 perl 模块,如下所示:

测试.pm

package Test;
use strict;
use warnings;
use Check;  
our $data = Check->getX;
1;

初始化.pm

package Initialize;
use Check;
use Test;

Check->setX(10);
our $t = $Test::data;
print $t;
1;

检查.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 中的语句 use Test 替换为 require Test;并将语句 Check->setX(10) 移到此 require 语句之前,然后 $data 被正确初始化为新值 10。在这种情况下发生了什么不同?

4

2 回答 2

1

Perl 在执行文件中的任何其他内容之前执行 use 语句。所以执行顺序是:

  1. use Check;
    1. $x = 12;
  2. use Test;
    1. use Check;- 这仅在文件已执行时才会导入
    2. $data = Check->getX();
  3. Check->setX(10);

如果您替换为指令,则userequire其余指令同时评估,并且如果您Check->setX(10);在要求之前移动,它将在进入测试之前进行评估

于 2013-02-25T21:57:44.733 回答
1

一般来说,模块很少或没有可执行代码。面向对象的模块只定义对象方法,有时还定义一些类数据。

当你编译并执行use Test整个 of时,此时设置的值。Test.pm$data

调用setX之后直接发生,但为时已晚,无法影响$data.

正如我在评论中所说,您的代码结构非常奇怪,模块之间根本不应该有时间依赖性。您确实应该从模块中删除所有可执行语句,但是要强制您的代码执行您可以编写的操作

use strict;
use warnings;

use Check;
BEGIN {
  Check->setX(10);
}
use Test;

our $t = $Test::data;
print $t;

但不要那样做!

于 2013-02-25T23:49:36.220 回答