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是标准的,这意味着通过代码的进一步维护者可以理解,也可以打印整齐栈跟踪经由confess或cluck或者甚至print Carp::longmess(见DOC).
*无论如何这都很好
会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)