2016-05-14 7 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. Compile фазы
    1. Compile use strict;.
    2. Выполнение require strict;.
    3. Выполнение import strict;.
    4. Компиляция use warnings;.
    5. Выполнение require warnings;.
    6. Выполнение import warnings;.
    7. Компиляция our($foo) = 0;. (Только создает $foo.)
    8. Compile BEGIN блок:
      1. Compile $foo = 2;.
    9. Выполнить BEGIN блок:
      1. Execute $foo = 2;.
    10. Компиляция our($bar);. (Только создает $bar.)
    11. Compile BEGIN блок:
      1. Compile $bar = 3;.
    12. Выполнить BEGIN блок:
      1. Execute $bar = 3;.
    13. Компиляция print "FOO: <$foo>\n";.
    14. Компиляция print "BAR: <$bar>\n";.
  2. Продолжительность фазы
    1. Выполнить ($foo) = 0;.
    2. Выполнение ($bar);.
    3. Execute print "FOO: <$foo>\n";
    4. Выполнить print "BAR: <$bar>\n";

Как вы можете видеть,

  • Вы назначаете 2 к $foo в 1.9.1, то вы назначаете 0 к $foo в 2.1.
  • Вы назначаете 3 в $bar в 1.12.1.
+1

Различие между инициализацией и простым назначением является ключом к тому, чтобы помочь мне понять это, а не просто зная об этом - спасибо. –

+0

Не имеет смысла, чтобы 'наш' имел инициализатор, поскольку' наш $ foo' создает псевдонимы с лексической областью для переменной пакета с тем же именем (как '\ my $ foo = \ $ PACKAGE: : foo; 'делает). Тем не менее, это просто назначение для меня. (Почему вы используете 'our' в первую очередь ???) – ikegami

+0

Мне нужна была переменная с областью действия в пакетной области. –