我熟悉调用者函数,程序可以使用它来知道它是从哪里调用的,从哪个文件,包等。有没有一种简单的方法让程序知道调用者的嵌套深度?用例是添加一些调试行,而不必显式计算嵌套级别。
我不是在寻找堆栈跟踪。我试图找出调用函数在另一个函数范围内的嵌套深度。
例如:
sub my_debug {
my ($txt) = @_;
my ($package, $filename, $line) = caller;
# Is there a way to know how deeply nested the caller is?
my $level = ... # How to get this?
print "DEBUG: You are calling from package $package in $filename "
. "line $line nesting level $level: MSG: $txt\n";
}
sub badly_nested {
for my $i ( 1..10 ) {
# 1-level deep
for my $j ( 1 .. 10 ) {
# 2-levels deep
my_debug( "j is $j" );
for my $k ( 1 .. 10 ) {
# 3-levels deep
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
CPAN 上可用的 Perl 模块 Scope::Upper 将有助于您的要求:
use strict;
use warnings;
use Scope::Upper qw(SCOPE);
print SCOPE(), "\n";
{
print SCOPE(), "\n";
{
print SCOPE(), "\n";
{
print SCOPE(), "\n";
}
print SCOPE(), "\n";
}
print SCOPE(), "\n";
}
print SCOPE(), "\n";
Run Code Online (Sandbox Code Playgroud)
这段代码的输出是:
0
1
2
3
2
1
0
Run Code Online (Sandbox Code Playgroud)
因此,它将使您能够查看当前范围的深度,这可用于推断嵌套循环的深度。您可以将偏移量传递给SCOPE()函数。因此,例如,如果您调用{SCOPE(1)}返回值将为零,尽管是一个范围深。这在您不关心自己是在子例程或if块内部的情况下很有用,因此想要开始更深入地计数。例如:
if ($foo) {
foreach my $x (1..10) {
foreach my $y (1..10) {
print SCOPE(1), "\n";
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这个示例中,响应将显示范围深度为 2 而不是 3,因为传递一个 1 来SCOPE()暗示它忽略if(){...}块的范围。