Каковы наилучшие методы обработки ошибок в Perl?

Я изучаю Perl, и во многих примерах я вижу, что ошибки обрабатываются следующим образом

open FILE, "file.txt" or die $!;

Является die в середине script действительно лучшим способом справиться с ошибкой?

Ответы

Ответ 1

Соответствие die в середине script действительно зависит от того, что вы делаете. Если это всего несколько десятков строк, то это нормально. Небольшой инструмент с несколькими сотнями строк, затем подумайте, признайтесь (см. Ниже). Если это большая объектно-ориентированная система с большим количеством классов и взаимосвязанным кодом, то, возможно, объект исключения будет лучше.

признайтесь в пакете Carp:
Часто ошибка, которая привела к смерти, не находится на линии, о которой сообщает отчет. Замена die confess (см. Carp package) даст трассировку стека (как мы дошли до этой строки), что значительно облегчает отладку.

Для обработки исключений из встроенных функций Perl мне нравится использовать autodie. Он обнаруживает сбои от open и других системных вызовов и будет генерировать исключения для вас, не выполняя бит or die. Эти исключения можно поймать с помощью eval { } или, еще лучше, с помощью Try:: Tiny.

Ответ 2

Поскольку я использую Log::Log4perl почти везде, я использую $logger->logdie вместо die. И если вы хотите иметь больше контроля над своими исключениями, рассмотрите Exception::Class.

Лучше поймать исключения из Try::Tiny (см. его документацию, почему).

Ответ 3

Если у вас нет более конкретной идеи, тогда да, вы хотите умереть, когда произойдут неожиданные вещи.

  • Умирать при отказе открыть файл и дать имя файла лучше, чем система, сообщающая вам, что она не может читать или писать анонимному undefined.

  • Если вы говорите о "script", в общем, вы говорите о довольно простой части кода. Не слои, которые нуждаются в координации (обычно не). В Perl-модуле есть общая идея: вы не владеете средой исполнения, поэтому либо основное программное обеспечение заботится, и оно ловит вещи в eval, либо на самом деле это не очень важно и умереть. Тем не менее, вы должны попробовать немного более уверенно в качестве модуля и просто передать обратно undefs или что-то еще.

  • Вы можете поймать любые штампы (или каркасы) в блоке eval. И вы можете сделать свою более конкретную обработку там.

  • Но если вы хотите проверить $! затем напишите этот код, и у вас будет более конкретное разрешение.

  • Взгляните на почти универсальный стандарт использования strict. Этот код, который умирает от сомнительного синтаксиса, вместо того, чтобы позволить вам продолжить.

Итак, я думаю, что общая идея такова: да, DIE, если у вас нет лучшего представления о том, как нужно обрабатывать вещи. Если вы вложите в него достаточную дальновидность, вы можете быть прощены за один или два раза, когда вы не умрете, потому что знаете, что вам не нужно.

Ответ 4

Более современный подход заключается в использовании стандартной библиотеки Carp.

use Carp;
my $fh;
open $fh, '<', "file.txt" or confess($!);

Главное преимущество - это трассировка стека при смерти.

Ответ 5

Я использую die, но я обертываю его в eval-блоки для управления обработкой ошибок:

my $status = eval
{
    # Some code...
};

Если сбой "eval":

  • $status будет undefined.
  • [email protected] будет установлено любое сообщение об ошибке (или содержимое a die)

Если "eval" преуспевает:

  • $status будет последним возвращенным значением блока.
  • [email protected] будет установлено в '..