没有办法让我的代码(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();