2013-02-25 105 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