如何打印所有执行的子程序?

Pau*_*kov 5 perl trace call-graph

例如我有以下 Perl 脚本

{ 
    package A;

    {
        package B;

        sub _y {
            print "Just Another Perl Hacker\n";

        }

    }

    sub _x {
        print "Hello world!\n";
        B::_y();
    }
}


use strict;
use warnings;

_x();
Run Code Online (Sandbox Code Playgroud)

如何将带有包限定符的每个执行子打印到 STDERR 或任何日志文件?

例如,从上面的脚本中,我希望看到以下输出:

1 A::_x()
2 B::_y()
Run Code Online (Sandbox Code Playgroud)

我认为可以使用像 Devel::NYTProf 这样的调试器,但我还没有找到特定的调试器模块或它们的参数来完成这个简单的任务。

有任何想法吗?

mob*_*mob 5

考虑调试模块会让您走上正轨。当启用调试模式时,PerlDB::DB()在程序的每个执行步骤中调用该函数。从这里,您可以从内置函数中提取子例程名称caller(其中将包括包名称),并按照您认为合适的方式输出它。

Devel/AllSubs.pm从路径中某处调用的文件开始@INC

package Devel::AllSubs;
my $count = 0;
my $last_sub = '::';
sub DB::DB {
    my ($pkg, $file, $line,$sub) = caller(1);
    if ($sub ne $last_sub) {
        print STDERR ++$count," $sub\n";
        $last_sub = $sub;
    }
}
1;
Run Code Online (Sandbox Code Playgroud)

然后运行你的程序

$ perl -d:AllSubs script.pl
Run Code Online (Sandbox Code Playgroud)

示例输出:

1 A::_x
Hello world!
2 B::_y
Just Another Perl Hacker
Run Code Online (Sandbox Code Playgroud)


mel*_*ene 4

可以使用标准 perl 调试器来完成:

$ PERLDB_OPTS="NonStop frame=1" perl -d prog.pl
  entering CODE(0x260cd78)
   entering strict::import
  entering CODE(0x260cd18)
   entering warnings::import
Package try.pl.
  entering DB::Obj::_init
  entering A::_x
Hello world!
   entering B::_y
Just Another Perl Hacker
Run Code Online (Sandbox Code Playgroud)

(请注意,我必须更改_x();A::_x();才能让您的代码运行。)

如果要将输出放入文件中,请添加LineInfo=filenamehere. perldoc perldebug详情请参阅。(特别是,如果您将选项更改为frame=2,您还会收到从子例程返回的消息。)

这些CODE参考资料适用于语句BEGIN周围的隐式块use

use strict;
Run Code Online (Sandbox Code Playgroud)

真正意思

BEGIN {
    require "strict.pm";
    strict->import();
}
Run Code Online (Sandbox Code Playgroud)