Подтвердить что ты не робот

Возврат сообщений об ошибках из подпрограмм perl

Это хороший способ вернуть сообщения об ошибках из подпрограммы в perl?

sub some_subroutine{
    # do something
    $something = 14;

    if(1 == 2){
        $_ = "This should not be happening!";
        return undef;
    }
    return $something;
}

my $ret=some_subroutine();
print "ERROR: $_" unless(defined $ret);

Код работает нормально (в параллельном мире, где 1 == 2), но с помощью $_ для возврата сообщения об ошибке является хорошим способом? Я не нашел никакой документации относительно использования $_ для таких целей.

Спасибо!

4b9b3361

Ответ 1

$_ не является хорошим механизмом, так как многие другие используют и устанавливают его.

Вы можете установить другую глобальную переменную, например $Error, но лучший способ - это исключение. Тогда пользователь не должен всегда проверять и забывать, это просто происходит. В Perl исключения генерируются с помощью die ". die возьмет строку или объект. Существует несколько модулей, облегчающих исключения броска, включая Exception::Class, Exception::Simple, Ouch и autodie.

Вы можете поймать исключение с eval {}, но есть ряд проблем с этим, поэтому вы должны использовать что-то вроде Try::Tiny.

Ответ 2

Нельзя использовать глобальную переменную для хранения сообщения об ошибке. Например, встроенная функция использует $!, а DBI использует $DBI::errstr. Но тогда вы наследуете все проблемы использования глобальных переменных. Обработчики сигналов должны локализовать их, деструкторы могут сжимать их, многопоточные проблемы и т.д.

Мне кажется, что выбор исключений (например, использование die) является более распространенным выбором.

Что бы вы ни делали, не используйте $_. Он часто сглаживается чем-то, поэтому его использование может иметь непреднамеренные последствия.

Ответ 3

Одна вещь, которую вы можете сделать, чтобы сделать это немного лучше, - просто return; на ошибке /undefined. Существуют контексты, где return undef; можно оценить как true. Вы можете проверить главу Perl Best Practices об обработке ошибок, поскольку она охватывает это и имеет другие хорошие указатели.

Например, если:

my $ret=some_subroutine();
print "ERROR: $_" unless(defined $ret);

становится

my @ret=some_subroutine();         # oops!
print "ERROR: $_" unless(defined $ret);

У вас есть странная ошибка (не поймать ошибку), которую трудно отследить, тогда как если вы return; от some_subroutine, вы получите:

my @ret=some_subroutine();         # oops!
print "ERROR: $_" unless($ret);    # but error is still caught

Кроме того, в случае функции, которая должна возвращать список:

my @ret=some_other_subroutine();    # OK
print "ERROR: $_" unless($ret);     # error will be caught if you "return;"

# ... but later ...

my $ret=some_other_subroutine();    # oops!
print "ERROR: $_" unless($ret);     # if you "return;" $ret will equal 0
                                    # (the length of the returned list)
                                    # and the error will be caught

Итак, хотя существуют другие шаблоны для возврата статуса ошибки / undefined из функции, всегда используя return; позволяет использовать один шаблон для почти всех функций, как для возврата соответствующего значения, так и при наступлении времени проверьте состояние ошибки.

Ответ 4

Это полностью зависит от того, какое поведение вы ожидаете увидеть от обработчика ошибок. В perl очень часто используется die или warn, если возникает ошибка/предупреждение о запуске.

Взгляните на этот учебник по обработке ошибок в perl: http://www.tutorialspoint.com/perl/perl_error_handeling.htm

Ответ 5

Для веб-службы вы можете написать подпрограмму для печати пользовательских ответов об ошибках (ошибки 40x и т.д.).