Какова польза блоков CHECK, UNITCHECK и INIT в Perl?

Я знаю, что они все делают, но никогда не оказывался в ситуации, когда я нуждался в любом из них. Во многих случаях я использовал блоки BEGIN и END. BEGIN особенно полезен, когда вам нужно настроить среду до запуска кода, и я использовал END в некоторых ситуациях отладки, чтобы улавливать важную информацию о состоянии для неуправляемых ошибок с жестким треком.

Вы когда-нибудь использовали CHECK, UNITCHECK или INIT? Если да, зачем? А по какой-то причине блок BEGIN не хватило бы?

Документация для блоков находится на PerlDoc.

Ответы

Ответ 1

У меня была функция пакета import, которая выполняла бы большую обработку, а затем вызывала вызов eval. Как вы отлаживаете что-то подобное? Функция импорта запускается, когда вы use модуль, который имеет место во время компиляции (например, в блоке BEGIN). По какой-то причине (я думаю, это связано с тем, что мне нужно было передавать параметры import с помощью записи heredoc, но это могло быть что-то еще), было недостаточно сказать require Module; Module->import(@args).

Итак, моим обходным путем было построение строки для eval в import и сохранение ее другой переменной. Затем я запустил eval в блоке INIT. Когда вы запускали отладчик, первая точка выполнения была в начале блока INIT, и я мог использовать отладчик для выполнения инструкции eval.

Ответ 2

Интересное использование блоков CHECK содержится в "Расширенном программировании на Perl" Саймона Козенса (O'Reilly) в главе 1 в разделе "Делать вещи позже с CHECK". Он показывает, как реализовать "окончательный" java-атрибут

Кроме того, Devel:: Sub:: Trace использует блоки INIT для включения следов (эта информация относится к POD для Devel:: Hook, который является модулем, используемым для работы с этими именованными блоками)

Ответ 3

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

Я написал обертку script, чтобы сделать все, что было сделано в шаблоне, который произошел в нескольких сотнях скриптов.

  • Были вещи, которые я должен был сделать, чтобы получить чтение модуля use -d. Это я побежал в блоках BEGIN и import sub.
  • Но был и тот шаблон, который инициализировал сервисы, которые будет использовать script. Поэтому я выполнил эти действия в блоках INIT.
  • И выполнил необходимый код очистки и выхода в блоках END.

Я думаю, что CHECK имеет смысл, если вы пишете модули с двигателями XS, но я использовал их только несколько раз. Однажды я думаю, что нужно было проверить предложения в Intermediate Perl. И я не могу забыть другие причины.

Но я использую блоки INIT, когда чувствую, что код является большей частью script, чем настройка модуля. По сути, я делаю только то, что необходимо во время компиляции.

Ответ 4

perlmod объясняет эти специальные блоки, но на самом деле используются только BEGIN и END. Это всего лишь массивы CV, LIFO или FIFO. Эти блоки позволяют выполнять отдельные тайминги при запуске кода независимо от местоположения в исходном файле. Таким образом, вы можете хранить разделы кода вместе, но они выполняются в разное время (PHASES).

CHECK был добавлен сначала для запуска пакета компилятора O (-MO=C...) в фиксированном порядке после инициализации модуля (использование пакета) и перед основной программой, чтобы сохранить там контекст выполнения. Это отделяет время компиляции (до) от времени выполнения (после). perl -c останавливается после ПРОВЕРКИ.

Поскольку я являюсь разработчиком компиляторов, я использую CHECK и -MO = широко. Мои модули compile() методы вызывается O внутри блока CHECK. С Один (отладка O) я вызываю метод compile не в CHECK, а позже в INIT, поэтому отладчик переходит в него. Отладчик не переходит в блоки CHECK по умолчанию, вы должны принудительно использовать его с помощью $DB::single=1 или использовать Od.

UNITCHECK был добавлен позже к компиляции и загрузке мелкозернистого модуля, особенно. .pmc.

Я никогда не использовал это до сих пор. Это также может произойти во время выполнения, поэтому я могу использовать его для проверки типов загружаемых модулей времени выполнения.

INIT был добавлен, чтобы разрешить отдельную инициализацию класса.

Я редко использую это, но это удобно.