Использование <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cfeb8f">[email protected]</a>для передачи сообщения об ошибке в модуле - программирование
Подтвердить что ты не робот

Использование [email protected]для передачи сообщения об ошибке в модуле

Я работал над вилкой модуля CPAN, который теперь не поддерживается (насколько я мог рассказать). В этом модуле они используют [email protected] для передачи сообщений об ошибках в стек. Другими словами, они устанавливают [email protected], если что-то пойдет не так в любом вызове подпрограмм, и они проверяют после вызова, чтобы убедиться, что он установлен. Я никогда не видел эту переменную раньше, но я думал, что это полезно, поэтому я начал использовать ее так же в коде. Теперь я недавно немного почитал об этом и обнаружил, что его назначение немного более узкое, чем это. Чтение perlvar (и другие вопросы SO по этому вопросу) не полностью отвечает за меня, но, нормально ли использовать [email protected] таким образом? Некоторые переменные "пунктуации", которые я знаю, определенно не должны использоваться таким универсальным способом (некоторые даже с local), является ли это одним из этих случаев, или я в порядке продолжаю эту практику?

4b9b3361

Ответ 1

[email protected] является относительно "неспешной" специальной переменной в Perl. Ничто в Perl никогда не читает от [email protected], и оно записывается только блоком eval {} в конце. Это делает его относительно безопасным для использования в собственных целях сигнализации.

В частности, ядро ​​модулей IO::Socket модулей использует это, чтобы указать отказ от конструктора:

use IO::Socket::IP;
my $sock = IO::Socket::IP->new(...) or die "Cannot connect - [email protected]";

Более традиционный $! здесь непригоден, потому что $! имеет магию, которая обертывает конструкцию errno уровня libc; это означает, что его можно установить только на целочисленное значение errno, даже если оно может быть прочитано как число или строка. Потому что иногда могут возникать сбои, которые напрямую не связаны с значениями errno (в случае IO::Socket, например, для многих видов сбоев resolver), иногда $! не подходит для этого.

Ответ 2

[email protected] обычно не устанавливается явно. Скорее, он автоматически устанавливается для вас, когда возникает исключение. Из perldoc die:

  • die LIST

    die вызывает исключение. Внутри eval сообщение об ошибке добавляется в [email protected], а eval заканчивается значением undefined. Если исключение не входит во все eval s, то неперехваченное исключение выводит LIST на STDERR и выходит с ненулевым значением. Если вам нужно выйти из процесса с помощью определенного кода выхода, см. exit.

Например,

#!/usr/bin/perl

eval {
    print "Hi\n";
    die "Something went wrong here";
    print "Bye\n";
};
print [email protected];

печатает

Hi
Something went wrong here at ./cr22854919 line 5.

Допустимо использовать [email protected] для передачи сообщений об ошибках в стек таким образом, как своего рода механизм try-catch. Однако, поскольку это глобальная переменная, вы должны обработать ее как можно скорее после блока eval { }, чтобы гарантировать, что никакой другой код не мешает вам обрабатывать исключение.


Другая магическая переменная, обычно используемая для обработки ошибок, - $!, которая работает как errno в C.

Пример:

my $path = "/tmp/no-such-file";
open F, '<', $path
    or print STDERR "$path: $!\n";

Вывод:

/tmp/no-such-file: No such file or directory