Как вы лучше всего приписываете ошибки в методе Perl вызывающей стороне - PullRequest
5 голосов
/ 14 июня 2011

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

foo(0);         # line 1

sub foo {
    1 / shift;  # line 4
}

выдает ошибку Illegal division by zero at foo.pl line 4, но я хочу Illegal division by zero at foo.pl line 1. Должно быть несколько способов, если я помещаю метод в модуль или если я обертываю тело метода в eval, но я не нашел такого простого способа, как этот:

sub foo {
    attributeErrorsToCaller; # do some magic
    1 / shift;
}

Есть ли такой способ?


РЕДАКТИРОВАТЬ: ответ Мирод подходит не то, что я искал:

Foo::foo(0);         # line 1

package Foo;
use diagnostics -traceonly;
BEGIN { disable diagnostics; }

sub foo {
    enable diagnostics;
    1 / shift;       # line 9
}

Без enable diagnostics сообщение об ошибке Illegal division by zero at foo.pl line 9.. С enable diagnostics это все еще слишком многословно, но это также может быть полезно:

Uncaught exception from user code:
    Illegal division by zero at foo.pl line 10.
 at foo.pl line 10
     Foo::foo(0) called at foo.pl line 2

Бьюсь об заклад, я мог бы взломать диагностику , чтобы получить именно ту функцию, которую я хочу, но использование диагностики в качестве необработанного модуля, вероятно, более рекомендуется.

Ответы [ 3 ]

10 голосов
/ 14 июня 2011

Карп очень, очень близко к "do_some_magic", который вы запрашиваете. Например:

#!/usr/bin/perl -w 
use strict;

# I fork to be as close to natural die() as possible. 
fork() or Foo::foo();
fork() or Foo::bar();
fork() or Foo::baz();
sleep 1;

package Foo;
use Carp; 

sub foo { die "Some error (foo)"; }; 
sub bar { croak "Some error (bar)"; }; 
sub baz { bar(); };

Как видите, croak() действует почти как die(), но сообщает об ошибке вызывающей стороне (даже косвенно - см. Baz).

Однако он не будет обрабатывать 1/0 для вас - либо используйте eval (или даже Try :: Tiny ), либо проверьте входные значения * и скажите «деление на ноль» самостоятельно ,

Carp является стандартным, что означает , понятный для других сопровождающих вашего кода , а также может печатать аккуратные следы стека через confess или cluck или даже print Carp::longmess (см. Документ) ,

* что в любом случае хорошо

6 голосов
/ 14 июня 2011

Вам будет достаточно use diagnostics;? Он сбросит стек вызовов, поэтому вызывающего достаточно легко узнать.

Например, в вашем примере:

#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;


foo(0);

sub foo
  { 
    return 1/$_[0];
  }

дает это:

`Illegal division by zero at test_die line 12 (#1)
    (F) You tried to divide a number by 0.  Either something was wrong in
    your logic, or you need to put a conditional in to guard against
    meaningless input.

Uncaught exception from user code:
        Illegal division by zero at test_die line 12.
 at test_die line 12
        main::foo(0) called at test_die line 8
1 голос
/ 14 июня 2011

Не так, как вы описали.Вы можете реализовать Debug :: Trace для получения полной обратной трассировки.

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

http://perldoc.perl.org/functions/caller.html

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