1

以下に示すように、3つの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にロードされるものであることを強制するにはどうすればよいですか?

ここで、ステートメントuseInitalize.pmのTestをrequireTestに置き換える場合。そして、このrequireステートメントの前にステートメントCheck-> setX(10)を移動すると、$ 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全体をコンパイル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 に答える