【问题标题】:Is there an easy way for a perl program to know its nesting level?perl 程序是否有一种简单的方法可以知道它的嵌套级别?
【发布时间】:2018-07-13 17:04:33
【问题描述】:

我熟悉caller 函数,程序可以使用它来了解调用它的位置、从哪个文件、包等。有没有简单的方法让程序知道调用者嵌套的深度?用例是添加一些调试行,而不必显式计算嵌套级别。

我不是在寻找堆栈跟踪。我试图找出调用函数在另一个函数范围内的嵌套程度。

例如:

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
            }
        }
    }
}

【问题讨论】:

  • 谢谢@AbhiNickz,但我想知道的不是我有多少堆栈帧(堆栈跟踪会告诉你什么),而是嵌套的级别(if ... { if ... { if ... { for ... { } } } }。在 python 中,你可以计算前导空格并除以缩进量来解决这个问题。
  • 想象一下设置一个具有更高值的调试标志以获取有关内部循环的更多详细信息
  • 正确缩进你的代码,就像在 python 中一样
  • @Flying_whale 这可能适用于某些代码,但它很容易被带有{} 字符的引用字符串破坏,所以这将进入我需要一个完整的解析器路线...这是我试图避免的。使用Scope::Upper的解决方案效果很好,不需要重新解析任何东西。

标签: perl debugging


【解决方案1】:

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";            

这段代码的输出是:

0
1
2
3
2
1
0

所以它可以让你看到你当前范围的深度,可以用来推断嵌套循环的深度。您可以将偏移量传递给SCOPE() 函数。例如,如果您调用{SCOPE(1)},则返回值将为零,尽管它是一个作用域深度。这在您不关心自己在子例程或if 块内的情况下可能很有用,因此想要开始更深入地计数。例如:

if ($foo) {
    foreach my $x (1..10) {
        foreach my $y (1..10) {
            print SCOPE(1), "\n";
        }
    }
}

在此示例中,响应将显示范围深度为 2 而不是 3,因为将 1 传递给 SCOPE() 暗示它忽略 if(){...} 块的范围。

【讨论】:

    猜你喜欢
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 2012-07-08
    • 1970-01-01
    • 2020-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多