Perl-将try/catch与eval混为一谈

Perl-将try/catch与eval混为一谈,perl,exception-handling,eval,Perl,Exception Handling,Eval,如何从内部eval{}捕获异常 #!/usr/bin/perl use strict; use warnings; use Try::Tiny; use Exception::Class ('T'); use Data::Dumper; try { eval { T->throw("Oops"); }; } catch { print Dumper \$_; }; } 我们得到的不是Exception::Class子模

如何从内部eval{}捕获异常

#!/usr/bin/perl
use strict;
use warnings;

use Try::Tiny;
use Exception::Class ('T');

use Data::Dumper;

try {
    eval {
        T->throw("Oops");
    };
    } catch {
        print Dumper \$_;
    };
}

我们得到的不是Exception::Class子模块,而是标量。更准确地说,我有很多带有require的遗留代码,require似乎在内部使用eval。

如果在
eval
块中遇到异常,则该块的返回值为
undef
(或列表上下文中的空列表),Perl会设置带有错误消息的特殊变量
$@
。错误消息通常是一个简单的标量,但它可以是引用或祝福引用——设置它的一种方式是使用
die
调用的参数,任何类型的值都可以传递给该函数

try {
    eval {
        T->throw("Oops"); 1;
    } or do {
        warn "Exception caught in eval: $@";
        # rethrow the exception outside eval
        if (ref($@) eq 'T') {
            $@->rethrow;
        } else {
            T->throw("Oops: $@");
        }
    }
} catch {
    print Dumper \$_;
};

您可以按如下方式自动向上转换异常:

#!/usr/bin/perl
use strict;
use warnings;
use feature qw( say );

use Try::Tiny;
use Exception::Class ('T');

$SIG{__DIE__} = sub {
   die($_[0]) if !defined($^S);
   die($_[0]) if ref($_[0]) eq 'T';
   T->throw($_[0]);
};

try {
    die "foo";
} catch {
    say ref($_) || "Not reference";
    print $_;
};

try {
    T->throw("foo");
} catch {
    say ref($_) || "Not reference";
    say $_;
};

嗯,你为什么要用
eval
try
?只需取出
eval
!不要在引用标量时使用
print Dumper
print Dumper\@array
print Dumper\%hash
都可以。如果$@的行为可能不正确,请使用
,我无法理解您在这里解决的问题。当然,
catch
子例程可以同样轻松地过滤异常,而且不会太尴尬吗?我对OP的理解是,
try
块包含模糊的、不可变的
eval
调用,这些调用的异常必须作为
Class::exception