Устранение ошибок времени выполнения в Perl и преобразование в исключения

Perl в настоящее время реализует $SIG{__DIE__} таким образом, что он поймает любую ошибку, которая возникает, даже внутри блоков eval. Это имеет действительно полезное свойство, что вы можете остановить код в точную точку, где происходит ошибка, собрать трассировку стека фактической ошибки, обернуть ее в объекте и затем вызвать вручную с помощью этого объекта в качестве параметра.

Это злоупотребление $SIG{__DIE__} устарело. Официально вы должны заменить $SIG{__DIE__} на *CORE::GLOBAL::die. Тем не менее, эти два отдаленно не эквивалентны. *CORE::GLOBAL::die не вызывается при возникновении ошибки во время выполнения! Все, что он делает, это заменить явные вызовы die().

Меня не интересует замена матрицы.

Я особенно заинтересован в ловле ошибок во время выполнения.

Мне нужно, чтобы любая ошибка времени выполнения в любой функции на любой глубине в любом модуле заставляла Perl передавать мне контроль, чтобы я мог собирать трассировку стека и ретронировать. Это необходимо для работы внутри блока eval - один или несколько закрывающих блоков eval могут захотеть поймать исключение, но ошибка времени выполнения может быть в функции без включения eval внутри любого модуля из любого места.

$SIG{__DIE__} поддерживает это прекрасно - и я добросовестно служил мне пару лет или больше, но Силы, которые Be ™ предупреждают, что это фантастическое средство может быть уловлено в любое время, и я не хочу неприятного сюрприза один день вниз по линии.

В идеале для самого Perl они могли бы создать для этого новый сигнал $SIG{__RTMERR__} (сигнал переключения достаточно прост для меня, так как он только подключен в одном месте). К сожалению, мои убеждающие способности не заставили алкоголика взломать бутылку, поэтому, если предположить, что этого не произойдет, как именно нужно достичь этой цели, чтобы очистить ошибки во время выполнения?

(Например, другой ответ здесь рекомендует Carp :: Always, который... также зацепляет DIE!)

Ответы

Ответ 1

Просто сделай это. Я сделал это. Вероятно, все, кто знает об этом крючке, это сделали.

Это Perl; он по-прежнему совместим с десятилетиями. Я интерпретирую "устаревшие" здесь, чтобы обозначить "пожалуйста, не используйте это, если вам это не нужно, ew, gross". Но вы действительно нуждаетесь в этом, и, похоже, понимаете последствия, поэтому имейте это в виду. Я серьезно сомневаюсь, что незаменимая языковая функция уходит в ближайшее время.

И отпустите свою работу на CPAN, чтобы следующий разработчик не нуждался в повторном повторении этого. :)