你能知道你的代码什么时候在评估块内吗?



没有办法让我的代码(Perl 库中的方法)判断它是否从eval {}块中执行?

我想要的是这样的:

sub mySub {
    my $isInEval = isInEval();
    if ($isInEval) {
        # Do a dying thing
    } else {
        # Do a non-dying thing.
    }
}

对于与推出复杂性相关的问题,我无法将垂死和未消亡的代码折叠到同一个相同的代码块中,而不关心我们是否在 eval 中。

好的,想通了。 perldoc caller 说:

# 0 1 2 3 4
($package, $filename, $line, $subroutine, $hasargs,
# 5 6 7 8 9 10
$wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash)
= caller($i);

请注意,如果帧不是子例程调用,而是 eval,则$subroutine可能是 (eval)。在这种情况下,将设置其他元素$evaltext和 $is_require:如果框架是由 require 或 use 语句创建的,则 $is_require 为 true,$evaltext包含 eval EXPR 语句的文本。特别是,对于 eval BLOCK 语句,$subroutine 是 (eval) ,但$evaltext是未定义的。

我通过使用

perl -e 'use Data::D umper;sub x {

foreach my $i (0..5) { my @c=caller($i);p rint Data::D umper->Dump([\@c]

)} }; sub y1 { x()}; sub z { eval{y1()} }; sub z2{z();}; z2()'

事实上,调用 #4 的输出caller[3]

$VAR1 = [
      'main',
      '-e',
      1,
      '(eval)',
      0,
      undef,
      undef,
      undef,
      0,
      ''
    ];

最终代码:

 sub isInEval{ 
     my $i=0; 
     while(1) {
        my ($package, $filename, $line, $subroutine, $hasargs
           ,$wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash)
            = caller($i); 
        last unless defined $package; 
        $i++; 
        if ($subroutine eq "(eval)" || $evaltext) { 
            return 1;
        } 
    }; 
    return 0; 
}
sub x {
    if (isInEval()) {
        print "evaln";
    } else {
        print "NO evaln";
    }
}
sub y1 { x() }; 
sub z1 { eval{y1()} }; 
sub w1 { z1(); }; 
print "w1: eval expected: ";
w1();
sub y2 { x() }; 
sub z2 { y2() }; 
sub w2 { z2(); }; 
print "w2: eval UNexpected: ";
w2();

最新更新