BEGIN, UNITCHECK, CHECK, INIT и END

| 0 TrackBacks

Ниже представлен вольный перевод параграфа из страницы документа perlmod - BEGIN, UNITCHECK, CHECK, INIT and END

Пять специально именованных блоков кода выполняются во время запуска и завершения программы Perl, Этими блоками являются BEGIN , UNITCHECK , CHECK , INIT , и END .

Блоки могут быть объявлены c префиксом sub чтобы создать видимость подпрограммы (хотя это не считается хорошим стилем). Следует отметить, что они на самом деле не существуют как именованные подпрограммы (несмотря на их внешний вид). Вы можете объявлять несколько таких блоков в программе и каждый из них будет выполнен в подходящий для каждого из них момент. Поэтому вы не можете вызвать любой из этих блоков кода, как обычную подпрограмму.

Блок BEGIN выполняется как можно раньше, то есть, сразу после того как он полностью определен, даже перед остальным содержимым файла (или строки), который был проанализирован. Вы можете использовать несколько BEGIN блоков в файле (или в eval'ed строки ) - они будут выполняться в порядке определения.

Вследствие того, что блог BEGIN выполняется немедленно, он может тянуть за собой определения подпрограмм, а так же из других файлов во время видимых в остальной скомпилированной и выполненной части. После того, как BEGIN сработан, он сразу становится неопределенным и любой код, который он использовал возвращается в пул памяти Perl.

     --EN--
    Because a C<BEGIN> code block executes immediately, it
    can pull in definitions of subroutines and such from
    other files in time to be visible to the rest of the
    compile and run time.  Once a C<BEGIN> has run, it is
    immediately undefined and any code it used is returned
    to Perl's memory pool. 

Следует отметить, что блоки BEGIN и UNITCHECK срабатывают внутри строк, скомпилированных в eval(). Блоки кода CHECK и INIT не выполняются внутри строк eval, что может привести к проблемам в среде mod_perl.

Блок кода END выполняется как можно позже, т.е после того, как perl завершил выполнение программы и непосредственно перед выходом интерпретатора, даже если программа завершается в результате вызова функции die(). (Но только, если это не морфинг в другую программу через exec, или программа не завершена по системному сигналу). Вы можете определять несколько блоков END в файле, они будут выполняться в обратном порядке их определения, а именно по принципу: последним пришел, первым вышел (LIFO). Блоки END не выполняются когда при запуске программы вы указываете ключ -c или если компиляция программы не удалась.

Обратите внимание, что блок кода END НЕ выполняется после завершения выполнения кода в eval(): если любой END блок создан в строке eval(), он будет выполнен так же как и любые другие END блоки этого пакета в порядке LIFO перед выходом интерпретатора.

Внутри блока END переменная $? содержит статус, означающий, что программа собирается вызвать exit(). Вы можете менять $? это значение выхода из программы. Остерегайтесь случайного изменения $? (например, в результате выполения другой программы через system()).

Блоки кода UNITCHECK , CHECK и INIT полезны, когда нужно что либо сделать между этапом компиляции и этапом исполнения основной программы.

Блоки UNITCHECK выполняются сразу после секции которая после их определения была скомпилирована. Основная часть программы и каждый загруженый модуль части компилации, как строка в eval, код, скомпилированный в конструкции (?{ }) в регулярных выражениях, вызовы в do FILE , require FILE , и код после ключа -e в командной строке.

     --EN--
    C<UNITCHECK> blocks are run just after the unit which
    defined them has been compiled.  The main program file
    and each module it loads are compilation units, as are
    string C<eval>s, code compiled using the C<(?{ })>
    construct in a regex, calls to C<do FILE>, C<require
    FILE>, and code after the C<-e> switch on the command
    line. 

Блоки кода CHECK выполняются только после завершения этапа компиляции кода и перед выполнением основного кода, в порядке LIFO(последним пришел - первым вышел). Блок CHECK используется компилятором Perl, чтобы сохранить скомпилированное состояние программы.

Блоки INIT запускаются непосредственно перед тем как Perl начнет выполнять программу, в порядке "первым пришел, первым вышел" (FIFO).

Блоки CHECK и INIT не будут выполняться внутри строки eval(), если это происходит после окончания основной фазы компиляции; что может быть проблемой в mod_perl и в другой постоянной среде, которая использует eval STRING для загрузки кода во время исполнения.

При использовании ключей командной строки -n и -p, блоки BEGIN и END работают как в awk. Блоки BEGIN и CHECK также выполняются когда программа запускается с ключом -c для проверки синтаксиса, хотя основной код не выполняется.

   #!/usr/bin/perl
  
  # begincheck
  
  print         "10. Обычный код выполняется во время исполнения программы.\n";
  
  END { print   "16.   Так это и есть конец истории.\n" }
  INIT { print  " 7. Блоки INIT выполняются непосредственно перед выполнением основной части программы.\n" }
  UNITCHECK {
    print       " 4.   И поэтому перед любыми блоками CHECK.\n"
  }
  CHECK { print " 6.   Так, это в шестой строке.\n" }
  
  print         "11.   Это, разумеется выполняется в общей очереди.\n";
  
  BEGIN { print " 1. Блоки BEGIN выполняются во время компиляции в порядке FIFO.\n" }
  END { print   "15.   Читайте perlmod чтобы узнать всю историю.\n" }
  CHECK { print " 5. Блоки CHECK выполняются в порядке LIFO после компиляции всей программы.\n" }
  INIT { print  " 8.   Выполняет это также при использовании ключа -c.\n" }
  
  print         "12.   Это анти-темный(anti-obfuscated) код.\n";
  
  END { print   "14. Блоки END выполняются в порядке LIFO после завершения основной программы.\n" }
  BEGIN { print " 2.   Так это строка выходит второй.\n" }
  UNITCHECK {
   print " 3. Блоки UNITCHECK выполняются в порядке LIFO после завершения компиляции файла.\n"
  }
  INIT { print  " 9.   Вы увидите разницу сразу.\n" }
  
  print         "13.   Хотя визуально строка последняя, это не должно вводить вас в заблуждение.\n";
 

No TrackBacks

TrackBack URL: http://blog.perl5doc.ru/mt-tb.cgi/3

Statistic

About this Entry

This page contains a single entry by Dinar published on February 24, 2010 1:30 AM.

perluniintro/Юникод is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.