问题描述
||
给定一种可能因警告和/或错误而失败的方法,我希望error方法显示在调用方处。杉木实例此脚本:
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;
}
有这种方法吗?
编辑:mirod \的答案接近不是我在寻找什么:
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
我敢打赌,我可以破解诊断程序以确切地获得我想要的功能,但是可能更建议使用诊断程序作为原始模块。
解决方法
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
, 鲤鱼非常非常接近您要的“ 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
甚至even19ѭ打印整齐的堆栈跟踪信息(请参阅文档)。
*反正很好
, 不像你描述的那样。您可以实现Debug :: Trace进行完整的追溯。
您可能还会发现perlcaller
,对于这种类型的调试非常有用。但是对于实时应用程序,您可能需要进行更详细的跟踪。
http://perldoc.perl.org/functions/caller.html