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

问题描述

|| 给定一种可能因警告和/或错误而失败的方法,我希望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进行完整的追溯。 您可能还会发现perl
caller
,对于这种类型的调试非常有用。但是对于实时应用程序,您可能需要进行更详细的跟踪。 http://perldoc.perl.org/functions/caller.html