你如何最好地将Perl方法中的错误归因于调用者

Jak*_*kob 5 error-handling perl

给定一个可能因警告和/或错误而失败的方法,我希望错误方法显示在调用者处.这个脚本的Fir实例:

foo(0);         # line 1

sub foo {
    1 / shift;  # line 4
}
Run Code Online (Sandbox Code Playgroud)

产生错误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;
}
Run Code Online (Sandbox Code Playgroud)

有这样的方式吗?


编辑: mirod的答案接近而不是我想要的:

Foo::foo(0);         # line 1

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

sub foo {
    enable diagnostics;
    1 / shift;       # line 9
}
Run Code Online (Sandbox Code Playgroud)

没有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
Run Code Online (Sandbox Code Playgroud)

我打赌我可以破解诊断以获得我想要的功能,但可能更推荐使用诊断作为原始模块.

Dal*_*aen 10

鲤鱼非常非常接近你要求的"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(); };
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,croak()行为几乎就像die(),但向调用者报告错误(甚至是间接的 - 见baz).

但是,它不会为你处理1/0 - 要么使用eval(或者甚至是Try :: Tiny),要么检查输入值*并自己说"除以零".

Carp是标准的,这意味着通过代码的进一步维护者可以理解,也可以打印整齐栈跟踪经由confesscluck或者甚至print Carp::longmess(见DOC).

*无论如何这都很好


mir*_*rod 6

use diagnostics;够吗?它将转储调用堆栈,因此调用者很容易找到.

例如,在您的示例中:

#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;


foo(0);

sub foo
  { 
    return 1/$_[0];
  }
Run Code Online (Sandbox Code Playgroud)

给出这个:

`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
Run Code Online (Sandbox Code Playgroud)