2013-02-25 106 views
1

假设我有三个perl模块如下给出:依赖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;并在此require语句之前移动语句Check-> setX(10),然后$ data被正确初始化为新值10. 这种情况在这种情况下发生了什么不同?

+2

我建议你不要打电话给Test.pm。 Test.pm是Perl附带的核心模块。看起来它现在没有出货,而且我不知道它何时停止发货,但是我会警惕与较老的Perls中的Test.pm冲突。 – 2013-02-25 22:01:37

+0

这不是真正的面向对象编程,因为你没有任何对象:唯一的方法是类方法。你应该真的只有简单的子程序,而不是把OO代码当作OO代码。此外,它看起来像'Initialize.pm'是一个*程序*(如果它是一个模块,你不应该运行它),所以它应该被称为'main.pl'或类似的东西。 – Borodin 2013-02-25 23:40:46

回答

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; 

但不这样做!

1

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

  1. use Check;
    1. $x = 12;
  2. 的文件已经执行
  3. $data = Check->getX();
  4. use Test;
    1. use Check; - 这不仅进口
  5. Check->setX(10);

如果用require更换use指令在同一时间的其他指示评估,如果移动Check->setX(10);在需要的时候,才在测试

的get之前评估
+0

什么时候应该使用require?在这里使用它可以吗? – prashanthkvs 2013-02-25 22:11:27

+1

只要您不输入子程序,就可以使用它。这里有助于澄清装货单。 – user1937198 2013-02-25 22:19:41

+0

通常你不应该使用'require'。几乎总是你想'使用',除非你正在寻找一个不寻常的加载顺序。 'use'不会做你想要的东西,因为你没有编写正确的模块(只包含声明和定义,并且没有可执行文件)。 – Borodin 2013-02-25 23:52:49