当前位置:  开发笔记 > 编程语言 > 正文

如何在Perl中获得调用堆栈列表?

如何解决《如何在Perl中获得调用堆栈列表?》经验,为你挑选了5个好方法。

有没有办法在Perl脚本中的当前位置之前访问(打印输出)子+模块列表到任意深度的子调用?

我需要更改一些Perl模块(.pm).工作流通过cgi脚本从网页启动,通过在我需要使用数据的模块中结束的几个模块/对象传递输入.在某个地方,数据发生了变化,我需要找出原因.



1> Ovid..:

您可以使用Devel :: StackTrace.

use Devel::StackTrace;
my $trace = Devel::StackTrace->new;
print $trace->as_string; # like carp

它的行为类似于Carp的踪迹,但您可以更好地控制帧.

一个问题是引用是字符串化的,如果引用的值发生变化,您将看不到它.但是,你可以用PadWalker来打印一些东西来打印出完整的数据(尽管这会很大).


一个非常有用的选择:`perl -d:来自[Devel :: Confess]的Confess script.pl`(https://metacpan.org/pod/Devel::Confess).

2> Axeman..:

Carp::longmess 会做你想做的,这是标准的.

use Carp qw;
use Data::Dumper;
sub A { &B; }
sub B { &C; }
sub C { &D; }
sub D { &E; }

sub E { 
    # Uncomment below if you want to see the place in E
    # local $Carp::CarpLevel = -1; 
    my $mess = longmess();
    print Dumper( $mess );
}

A();
__END__
$VAR1 = ' at - line 14
    main::D called at - line 12
    main::C called at - line 10
    main::B called at - line 8
    main::A() called at - line 23
';

我想出了这个子(现在有可选的祝福'动作!)

my $stack_frame_re = qr{
    ^                # Beginning of line
    \s*              # Any number of spaces
    ( [\w:]+ )       # Package + sub
    (?: [(] ( .*? ) [)] )? # Anything between two parens
    \s+              # At least one space
    called [ ] at    # "called" followed by a single space
    \s+ ( \S+ ) \s+  # Spaces surrounding at least one non-space character
    line [ ] (\d+)   # line designation
}x;

sub get_stack {
    my @lines = split /\s*\n\s*/, longmess;
    shift @lines;
    my @frames
        = map { 
              my ( $sub_name, $arg_str, $file, $line ) = /$stack_frame_re/;
              my $ref =  { sub_name => $sub_name
                         , args     => [ map { s/^'//; s/'$//; $_ } 
                                         split /\s*,\s*/, $arg_str 
                                       ]
                         , file     => $file
                         , line     => $line 
                         };
              bless $ref, $_[0] if @_;
              $ref
          } 
          @lines
       ;
    return wantarray ? @frames : \@frames;
}



3> Leon Timmerm..:

调用者可以做到这一点,尽管您可能需要更多信息.



4> Thariama..:

此代码无需任何其他模块即可运行.只需在需要的地方加入.

my $i = 1;
print STDERR "Stack Trace:\n";
while ( (my @call_details = (caller($i++))) ){
    print STDERR $call_details[1].":".$call_details[2]." in function ".$call_details[3]."\n";
}



5> jkramer..:

还有Carp::confessCarp::cluck.

推荐阅读
小妖694_807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有