当我将此脚本作为perl -d:DB t.pl
运行时
$ cat t.pl
sub t { }
sub sb {
goto &t; # << The DB::goto is called from here
}
sb( a => 3 )
$ cat Devel / DB.pm
package DB;
BEGIN {
$^P |= 0x80;
}
sub DB {
}
sub goto {
local $" = ' - '; #"
my $level = 0;
while( my @frame = caller($level++) ) {
print "@frame[0..3,5]\n";
}
}
sub sub {
return &$DB::sub;
}
1;
sub t { }
sub sb {
goto &t; # << The DB::goto is called from here
}
sb( a => 3 )
&#39;来电者&#39;调用表格DB :: goto返回下一个信息:
DB - Devel/DB.pm - 19 - DB::goto -
main - t.pl - 5 - main::t -
因为 DB :: goto被perl internals称为普通子,我期待下一个输出:
main - t.pl - 3 - DB::goto -
main - t.pl - 5 - main::t -
有可能修复这种行为吗?如果是的话 在哪个方向挖掘来修复它?
答案 0 :(得分:1)
执行顺序是:
t.pl:5 sb( a => 3 )
[enter DB::sub]
Devel/DB.pm:19 return &$DB::sub;
[enter main::sb]
t.pl:3 goto &t;
[enter DB::goto]
当达到goto
时,最近的函数调用在第19行的Devel / DB.pm中,这样caller(0)
返回的是什么。 (请记住,goto &NAME
会改变调用堆栈。)
但听起来您想要报告调用goto
的行号和文件。不幸的是,我不认为你可以使用caller
执行此操作,因为caller
甚至不知道goto
:
sub foo {
goto &bar;
}
sub bar {
print join ' - ', caller, "\n";
}
foo();
__END__
main - bar - 9 - # line 9 is where foo() is called, not goto &bar
一种可能的解决方法是在DB::DB
中存储上次执行的命令的文件名和行号,然后在DB::goto
中的堆栈跟踪之前打印该值。不过,我还没有找到办法做到这一点。