Социальные сети

перевод статьи Peter Makholm Perl exception handling is hard

Всем хорошо известно, что обработка исключений в Perl реализуется при помощи eval и die, вместо try и catch.

eval {
    do_something()
        or die "Err!";
 };

if ($@) {
    print "Catched exception: $@";
}

Так советует делать Damian Conway в 16 главе своей книги Perl Best Practices и perldoc -f die. К сожалению, такая схема работает не во всех случаях. Рассмотрим пример:

#!/usr/bin/perl

package Foo;

sub new {
    my $class = shift;
    return bless {}, $class;
}

sub DESTROY {
    my $self = shift;
    eval { 1; };
}

package main;
eval {
    my $foo = Foo->new();
    open my $fh, ">", "/"
        or die "Could not open /: $!";
    print "Doing some work\n";
};
if ($@) {
    print STDERR "Something bad happened: $@\n";
} else {
    print "Everything went well\n";
}

Ввиду невозможноси открыть "/" для записи, мы ожидаем получить сообщение об ошибке. Но в реальности скрипт завершается успешно, хотя при этом не выводит "Doing some work". Что-же происходит? При выходе из области видимости $foo вызывается деструктор, в котором вызывается eval и изменяет значение $@.

Что можно сделать для решения проблемы? Прежде всего можно избежать модификации @_ в деструкторе. Добиться этого можно при помощи локализации @_. Даже если вы не используете eval явно, он может вызыватся где-то в глубине. Поэтому всегда начинайте писать деструктор по следующему шаблону:

sub DESTROY {
    my $self = shift;
    local $@;
    ...;
}

Скорее всего вы также захотите локализовать $?, но это уже другая история.

Еще одним вариантом решения будет изменение схемы эмуляции try/catch. В случае аварийного завершения блока eval возвращает значение undef. Поэтому можно явно прописать в блоке возврат "истинного" значения и заменить проверку $@ на логическое условие or.

eval {
    do_work();
    1;
} or {
    print "catch: $@";
}

Конечно, описание ошибки в $@ может быть некорректным, поэтому такой метод не так хорош, как вариант с деструктором. В случае использования модулей сторонних авторов вы можете реализовать многоуровневую схему используя оба приведенных решения. Я думаю, в Perl::Critic есть политика обрабатывающая вышеприведенную try/catch конструкцию.

Мне стало интересно, как модули обработки исключений с CPAN ведут себя с вариантом вызова деструктора. Я проверил два из них: Error.pm обрабатывает вызов дестуктора корректно, т.к. в нем исключение запоминается до вызова die. Более современный модуль TryCatch.pm, к сожалению, работает в таком случае некорректно (см. rt #46294), хотя он намного функциональнее.

Дополнение: Я планирую написать патч для TryCatch.pm, который реализует функцию throw, аналогично Error.pm.


Вам это будет интересно!

  • (c) Роберт Рождественский
  • cesbo.com: создание бэкапов (часть 1)
  • …пых)…
  • из черновика Маруси
  • Безымянный 80287


  • Последние новости


    Шаг 5. Выбираем фирменное наименование организации

    Если вы собираетесь регистрировать новое юридическое лицо, то перед вами неизбежно встают необходимость выбора его названия и ряд сопутствующих вопросов. Следует ли проверять выбранное наименование организации на уникальность перед подачей документов на регистрацию? Можно ли зарегистрировать компанию с таким же наименованием, как и у другой, уже существующей орган...
    Читать далее »

    Шаг 4. Выбор системы налогообложения

    Действующее налоговое законодательство позволяет налогоплательщику в некоторых случаях значительно уменьшить сумму уплачиваемых налогов путем грамотного выбора режима налогообложения. Выделяют общий режим налогообложения и специальные налоговые режимы, которые следует отличать от льготных режимов. При применении общего режима налогообложения налог...
    Читать далее »

    Аренда помещений

    Самым тесным образом с фактическим адресом организации связана Аренда Ею помещений, необходимых для налаживания выбранных видов деятельности. Для деятельности любой организации необходимо помещение. Однако недвижимость стоит сейчас очень дорого, и лишь немногие организации в состоянии приобрести помещение в собственность. В связи с этим значительная част...
    Читать далее »

    Шаг 3. Выбираем место нахождения организации

    МЕСТО НАХОЖДЕНИЯ ОРГАНИЗАЦИИ, ЕЕ ЮРИДИЧЕСКИЙ, ФАКТИЧЕСКИЙ И ПОЧТОВЫЙ АДРЕСА В ГК РФ приведено понятие «место нахождения юридического лица» – так называемый юридический адрес, официально зарегистрированный в ЕГРЮЛ. Однако юридическое лицо может располагаться и по другому адресу – фактическому. В гражданском законодательстве не содержит...
    Читать далее »

    Карточка

    С образцами подписей и оттиска печати ...
    Читать далее »

    Форма

    Документа, подтверждающего наличие лицензии Приложение 26 СЕРТИФИКАТ СООТВЕТСТВИЯ ...
    Читать далее »

    Уведомление

    О регистрации юридического лица в территориальном органе Пенсионного фонда Российской Федерации по месту нахождения На территории Российской Федерации Приложение 22 Свидетельство О регистрации страхователя в территориальном фонде Обязательного медицинского страхования При обязательном мед...
    Читать далее »