我的代码(Perl库中的方法)是否有办法判断它是否是从eval {}
块中执行的?
我想拥有的是:
sub mySub {
my $isInEval = isInEval();
if ($isInEval) {
# Do a dying thing
} else {
# Do a non-dying thing.
}
}
对于与推出复杂性相关的问题,我无法将死亡和非死亡代码折叠到同一个相同的代码块中,如果我们在eval内部,则无关紧。
答案 0 :(得分:1)
好的,明白了。 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),而是eval。在这种情况下,设置了额外的元素$ evaltext和$ is_require:如果框架是由require或use语句创建的,则$ is_require为true,$ evaltext包含eval EXPR语句的文本。特别是,对于eval BLOCK语句,$子例程是(eval),但$ evaltext是未定义的。
我使用
测试了这个perl -e'使用Data :: Dumper; sub x {foreach my $ i(0..5){my @ c = caller($ i); print Data :: Dumper-> 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 "eval\n";
} else {
print "NO eval\n";
}
}
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();