Может ли Perl-компилятор сказать мне, есть ли в моем коде непроверенное исключение? - PullRequest
3 голосов
/ 28 апреля 2010

Есть ли способ в Perl объявить, что метод может выдать ошибку (или умереть)?

РЕДАКТИРОВАТЬ: Что меня больше всего интересует, так это способ заставить компилятор или IDE сказать мне, что у меня есть неконтролируемое исключение где-то в моем коде.

Мне всегда нравилось, как в Java метод может обрабатывать исключение и / или генерировать его. Подпись метода позволяет поставить «throws MyException», поэтому хороший IDE / компилятор будет знать, что если вы используете указанный метод где-то в вашем коде, вам придется проверить исключение или объявить, что ваша функция «выбрасывает» исключение далее .

Я не могу найти что-то похожее в Perl. Мой коллега написал метод, который «умирает» при неправильном вводе, но я забываю eval-if ($ @) it ... offcourse ошибка была обнаружена только тогда, когда пользователь запускал приложение.

(конечно, я сомневаюсь, существует ли какая-либо IDE, которая могла бы найти такие вещи для Perl, но, по крайней мере, perl -cw должен быть в состоянии, нет?)

Ответы [ 4 ]

3 голосов
/ 28 апреля 2010

Два возможных ответа. Выберите то, что вам больше нравится:

  1. В Perl на это указывает POD модуля. Нет способа пометить его программно, поэтому вместо этого вам нужно полагаться на документацию.

  2. Любой метод может die или, по крайней мере, любой нетривиальный метод. Он будет вызывать что-то еще, что, вероятно, вызывает что-то другое и т. Д., Поэтому единственный способ гарантировать, что не будет выдано исключение, - это проследить все уровни (потенциальных) вызовов, чтобы убедиться, что там нет ничего, что могло бы 1012 *. Гораздо более прагматично просто предположить, что исключения всегда возможны и соответственно кодируются.

Отредактировано, чтобы добавить: Как правило, Perl5 и статический анализ кода не очень хорошо уживаются. Насколько я понимаю, это одна из причин изменения языка в Perl6, так что вам, возможно, повезет больше.

2 голосов
/ 28 апреля 2010

Не видел ничего подобного, но, может быть, атрибуты подпрограмм могут помочь вам?

Вот небольшое доказательство концепции с использованием Attribute::Handlers

ThrowsExceptionHandler.pm

package ThrowsExceptionHandler;
use Modern::Perl;
use Attribute::Handlers;

our @subs;

sub ThrowsException :ATTR(CODE) {
    push @subs, {
        package  => $_[0],
        symbol   => $_[1],
        subname  => *{$_[1]}{NAME},
        referent => $_[2],
        attr     => $_[3],
        data     => $_[4],
        phase    => $_[5],
        filename => $_[6],
        linenum  => $_[7],
    };
}

sub does_throw {
    my ($class, $subname) = @_;
    (grep { $_->{subname} eq $subname } @subs) ? 1 : 0;
}

1;

example.pl

use Modern::Perl;
use base qw(ThrowsExceptionHandler);

sub baz :ThrowsException {
    die "Throws error";
}

sub foo {
    warn "warning only";
}


say ThrowsExceptionHandler->does_throw( 'baz' );  # => 1
say ThrowsExceptionHandler->does_throw( 'foo' );  # => 0

Возможно (смесь) PPI, Perl::Critic и / или Padre можно приспособить для использования чего-то подобного?

/ I3az /

0 голосов
/ 28 апреля 2010
0 голосов
/ 28 апреля 2010

из документа " Исключения "

  1. $ @ не сообщает нам, где произошла ошибка

  2. Мы можем обойти это с помощью пользовательской функции:

    sub throw { мой $ mess = join ('', @_); $ mess = ~ s / \ n? $ / \ n /; мой $ я = 1; local $ "=" ',' "; пакет БД; while (my @parts = caller ($ i ++)) { мой $ q; $ q = "'" if @DB :: args; $ mess. = "-> $ parts3". "в $ parts 1 line $ parts 2 \ n"; } умри $ беспорядок; }

С этим вы также можете брать ссылки из " CPAN " и " Объектно-ориентированная обработка исключений в Perl "

...