2016-05-14 93 views
2

爲什麼未初始化變量的行爲/互動不同於一個初始化的變量在這種情況下:與我們並開始塊相互作用聲明的變量

use strict; 
use warnings; 

our($foo) = 0; 
BEGIN { 
     $foo = 2; 
} 

our($bar); 
BEGIN { 
     $bar = 3; 
} 

print "FOO: <$foo>\n"; 
print "BAR: <$bar>\n"; 

結果:

$ perl test.pl 
FOO: <0> 
BAR: <3> 

Perl版本:

$ perl -v 

This is perl 5, version 22, subversion 0 (v5.22.0) built for x86_64-linux 

回答

10

首先,它不是初始化程序;這是一個普通的舊任務。它在代碼執行時發生,而不是在創建變量時發生。

其次,BEGIN塊在編譯完成後立即進行評估。

這樣,你寫的基本上等同於以下內容:

# Compile phase 
use strict; 
use warnings;  
our $foo; 
$foo = 2; 
our $bar; 
$bar = 3; 

# Runtime phase 
($foo) = 0; 
($bar); 
print "FOO: <$foo>\n"; 
print "BAR: <$bar>\n"; 

更確切地說,

  1. 編譯階段
    1. 編譯use strict;
    2. 執行require strict;
    3. 執行import strict;
    4. 編譯use warnings;
    5. 執行require warnings;
    6. 執行import warnings;
    7. 編譯our($foo) = 0;。 (僅創建$foo。)
    8. 編譯BEGIN塊:
      1. 編譯$foo = 2;
    9. 執行BEGIN塊:
      1. 執行$foo = 2;
    10. 編譯our($bar);。 (僅創建$bar。)
    11. 編譯BEGIN塊:
      1. 編譯$bar = 3;
    12. 執行BEGIN塊:
      1. 執行$bar = 3;
    13. 編制print "FOO: <$foo>\n";
    14. 編譯print "BAR: <$bar>\n";
  2. 運行時相
    1. 執行($foo) = 0;
    2. 執行($bar);
    3. 執行print "FOO: <$foo>\n";
    4. 執行print "BAR: <$bar>\n";

正如你所看到的,

  • 您在1.9.1分配2$foo,那麼你在2.1分配0$foo
  • 您在1.12.1中將3指定爲$bar
+1

初始化和簡單賦值之間的區別是幫助我理解這一點的關鍵,而不是僅僅知道它 - 謝謝。 –

+0

'我們'有一個初始化器是沒有意義的,因爲'我們的$ foo'爲同名的包變量創建了一個詞法範圍的別名(就像'\ my $ foo = \ $ PACKAGE: :foo;'確實)。也就是說,這只是「我的」的任務。 (爲什麼你首先使用'our' ???) – ikegami

+0

我需要一個打包範圍的變量。 –