LINUX.ORG.RU

Как определить, что код выполняется в секции BEGIN {}?

 


0

1

У меня есть функция, которая считывает конфигурационный файл и на основе переменной PERL_LIBS в нём добавляет в @INC новые пути.

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

Пока что я передаю функции явным образом параметр-флаг «надо бы модифицировать @INC, если PERL_LIBS установлен».

Не углубляясь в рассуждения о том, как бы нам обустроить bashrc и /etc/profile.d - скажите, а есть ли теоретическая возможность «общего плана» узнать, на данный момент код работает в BEGIN {}, в каком-нибудь END {} или вообще в основной секции кода?

Спасибо!

★★★★★

Последнее исправление: DRVTiny (всего исправлений: 1)

Допустим, функция f() вызывается не внутри BEGIN, а в «основной секции», но это происходит в файле somecode.pm, который подключается через use somecode в файле script.pl. Тогда относительно script.pl функция f() вызывается внутри BEGIN, а относительно somecode.pm - нет.

annulen ★★★★★
()
Ответ на: комментарий от annulen
package SomePackage;
use strict;
use 5.16.1;

sub f {
  given ( (caller(1))[3] ) {
    print "BEGIN\n" when /::BEGIN$/;
    print "END\n" when /::END$/;
    default { print "NORMAL\n" }
  }
}

package main;
use strict;
BEGIN {
  SomePackage::f()
}

SomePackage::f();

END {
  SomePackage::f()
}

Вывод:

BEGIN NORMAL END

Круто! Спасибо :)

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от annulen

Так ведь жеж BEGIN-блоки каждого pm просто выполняются в порядке появления use'ов в main. А инициализационный код пакета (который не BEGIN) выполняется в общем потоке исполнения кода.

Собственно, если сделать так:

package SomePackage;
use strict;
use 5.16.1;

our $v=f(1);

sub f {
  given ( (caller(1))[3] ) {
    print "BEGIN\n" when /::BEGIN$/;
    print "END\n" when /::END$/;
    default { print "NORMAL\n" }
  }
  if (shift) {
    print "^ HERE\n";
  }
}

1;

- я получаю:

NORMAL
^ HERE

DRVTiny ★★★★★
() автор топика

Объявляй BEGIN и END блоки непосредственно в скрипте, а не в подключаемых модулях. Тогда будет точно ясно, что они в любом случае выполнятся вне зависимости от того, что там в модулях.

shell-script ★★★★★
()
% perl -wE 'sub f{say ${^GLOBAL_PHASE}};f;BEGIN{f};CHECK{f};END{f}'
START                                          
CHECK                                          
RUN                                            
END
disarmer ★★★
()
Последнее исправление: disarmer (всего исправлений: 1)
Ответ на: link fix от pru-mike

Да, спасибка. С рабочего компа как-то ниасилил.

outtaspace ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.