Как я могу заменить все "die" на "confess" в приложении Perl?
Я работаю в большом Perl-приложении и хотел бы получать трассировки стека каждый раз, когда вызывается die. Мне известен модуль Carp, но я бы предпочел не искать / заменять каждый экземпляр 'die' на 'confess'. Кроме того, я хотел бы, чтобы трассировки стека полностью содержали ошибки в модулях Perl или самом интерпретаторе Perl, и, очевидно, я не могу изменить их для использования Carp.
Итак, есть ли способ изменить функцию "die" во время выполнения, чтобы она работала как "confess"? Или есть параметр интерпретатора Perl, который будет генерировать трассировки полного стека из 'die'?
4 ответа
Используйте Devel:: SimpleTrace или Carp:: Always, и они сделают то, что вы просите, без какой-либо тяжелой работы с вашей стороны. Они имеют глобальный эффект, что означает, что их можно легко добавить всего за один запуск в командной строке, используя, например, -MDevel::SimpleTrace
,
Как насчет настройки __DIE__
обработчик сигнала? Что-то вроде
$SIG{__DIE__} = sub { Carp::confess @_ };
в верхней части вашего сценария? Смотрите perlvar %SIG для получения дополнительной информации.
Я обычно только хочу заменить die
немного кода, поэтому я локализую __DIE__
обработчик:
{
use Carp;
local $SIG{__DIE__} = \&Carp::confess;
....
}
В качестве инструмента разработки это может работать, но некоторые модули разыгрывают это, чтобы заставить свои функции работать. Эти функции могут ломаться странным образом, когда вы переопределяете ожидаемый ими обработчик. Это не очень хорошая практика, но иногда это случается.
Модуль Error преобразует все die
с Error::Simple
объекты, которые содержат полную трассировку стека (конструктор анализирует текст "at file... line.." и создает трассировку стека). Вы можете использовать произвольный объект (как правило, Error::Simple
) обрабатывать ошибки с $Error::ObjectifyCallback
предпочтение.
Это особенно удобно, если вы обычно выбрасываете исключения других типов, чтобы сигнализировать о других событиях, тогда как вы просто добавляете обработчик для Error::Simple
(или любой другой класс, который вы используете для ошибок), и пусть он создает свою трассировку стека или выполняет специализированное ведение журнала в зависимости от типа ошибки.