2016-06-09 4 views
0

Как я понимаю, эти специальные функции внутри кода Perl, блоки BEGIN и CHECK работают во время фазы компиляции, пока блоки INIT и END работают во время фактической фазы выполнения.Блоки BEGIN, CHECK, INIT & END в Perl

Я могу понять, используя эти блоки внутри реального кода Perl (библиотеки Perl), но как их использовать внутри модулей? Это возможно?

С тех пор, как мы используем use <Module-name>, модуль скомпилирован, поэтому в действительности выполняются блоки BEGIN и CHECK. Но как будут выполняться блоки INIT и END, поскольку код модуля, который, как я думаю, не работает в истинном смысле. Мы используем только определенные функции изнутри модулей.

+0

Это подробно описано в главе 16 «Компиляция», [Программирование Perl] (http://shop.oreilly.com/product/9780596004927.do) –

ответ

4

Short   специальные кодовые блоки в пакеты загружаются через use обрабатываются и запустить (или планируется запустить) в том же порядке и порядке, что и в main::, поскольку use сам по себе является блоком BEGIN.


Отличная документация по этому вопросу может быть найдена in perlmod. Из этого раздела

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

Поскольку use заявления являютсяBEGIN блоков они бегут, как только встречаются. От use

Это точно эквивалентно

BEGIN { require Module; Module->import(LIST); } 

So в BEGIN блоков в пакете работать в режиме онлайн с другими, так как они встречаются. Блоки END в пакете также скомпилируются в том же порядке, что и другие специальные блоки. Что касается порядка (возможного) выполнения, то Блок кода END выполняется как можно позже ... и

В файле может быть несколько блоков END - они будут выполняться в обратном порядке определения; что: последний, первым обслужен (LIFO)

Порядок составления и исполнения INIT и CHECK блоков следует примеру.


Вот какой код для демонстрации этих специальных блоков кода, используемых в пакете.

Файл PackageBlocks.pm

package PackageBlocks; 
use warnings; 

BEGIN { print "BEGIN block in the package\n" } 
INIT { print "INIT block in the package\n" } 
END { print "END block in the package\n" } 
1; 

Основной сценарий

use warnings; 

BEGIN { print "BEGIN in main script.\n" } 

print "Running in the main.\n"; 

INIT { print "INIT in main script.\n" } 

use PackageBlocks; 

END { print "END in main script.\n" } 
BEGIN { print "BEGIN in main script, after package is loaded.\n" } 

print "After use PackageBlocks.\n"; 

Выход

 
BEGIN in main script. 
BEGIN block in the package 
BEGIN in main script, after package is loaded. 
INIT in main script. 
INIT block in the package 
Running in the main. 
After use PackageBlocks. 
END in main script. 
END block in the package 

BEGIN блок в пакете выполняется в порядке появления, по сравнению с те, что указаны в main::, и до INIT. Блок END работает в конце, , а один в пакете запускается после одного в main::, так как перед ним в этом примере находится use.

+0

Это не касается вопроса OP, который о 'INIT' и' END' в модуле Perl – Borodin

+0

@Borodin О ... последний абзац меня подстегнул, спасибо. Я добавлю это. – zdim

1

Это очень легко проверить для себя

use Modulerequire EXPR и do EXPR и eval EXPR) компиляции кода Perl, а затем сразу же запустить его

Вот где 1; в конце большинства модулей подобрал. Если выполнение кода модуля после его компиляции не возвращает значение в верно то require потерпит неудачу

Правды там обычно не много пользы для INIT или END блока, поскольку фаза во время выполнения настолько тесно привязано к компиляции, и так как модули, как правило, об определении подпрограммы, но есть вариант, если вы хотите

Смежные вопросы