Perl-用eval搞乱try / catch

时间:2018-07-30 14:22:15

标签: 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子模块,而是标量。更准确地说,我有很多带有 require 的旧代码,并且要求似乎在其中使用了 eval

2 个答案:

答案 0 :(得分:1)

如果在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 \$_;
};

答案 1 :(得分:1)

您可以按如下所示自动上转换异常:

#!/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 $_;
};