【问题标题】:Perl print out all subs arguments at every call at runtimePerl 在运行时的每次调用中打印出所有 subs 参数
【发布时间】:2015-05-11 06:15:30
【问题描述】:

我正在寻找方法来调试从命名空间 Myapp::* 打印每个子例程调用(例如,不转储 CPAN 模块),但 无需手动编辑每个 .pm 文件插入一些模块或打印语句。

我刚刚学习(最好说:试图理解)package DB,是什么让我可以跟踪执行(使用 shebang #!/usr/bin/perl -d:Mytrace

package DB;
use 5.010;

sub DB {
    my( $package, $file, $line ) = caller;
    my $code = \@{"::_<$file"};
    print STDERR "--> $file $line $code->[$line]";
}

#sub sub {
#    print STDERR "$sub\n";
#    &$sub;
#}

1;

并寻找一种方法如何使用sub 调用从Myapp::* 的命名空间打印被调用sub 的实际参数。

或者这里有一些更简单(常用)的方法

  • 结合执行线追踪器DB::DB
  • 每个子例程调用参数(及其返回值,如果可能)的转储?

【问题讨论】:

    标签: perl


    【解决方案1】:

    我不知道它是否在这个词的任何理智含义中算作“更容易”,但是您可以遍历符号表并将所有函数包装在打印其参数和返回值的代码中.这是一个如何完成的示例:

    #!/usr/bin/env perl
    
    use 5.14.2;
    use warnings;
    
    package Foo;
    
    sub first {
        my ( $m, $n ) = @_;
    
        return $m+$n;
    }
    
    sub second {
        my ( $m, $n ) = @_;
    
        return $m*$n;
    }
    
    package main;
    
    no warnings 'redefine';
    
    for my $k (keys %{$::{'Foo::'}}) {
        my $orig = *{$::{'Foo::'}{$k}}{CODE};
        $::{'Foo::'}{$k} = sub {
            say "Args: @_";
            unless (wantarray) {
                my $r = $orig->(@_);
                say "Scalar return: $r";
                return $r;
            }
            else {
                my @r = $orig->(@_);
                say "List return: @r";
                return @r
            }
        }
    }
    
    say Foo::first(2,3);
    say Foo::second(4,6);
    

    【讨论】:

    • 您的意思可能是unless(wantarray)。 ;) 无论如何+1。 :) 效果很好,我什至可以拨打caller(1) 获取更多信息。但是,我会稍等一下接受 - 我正在寻找使用 DB 包(尤其是 @DB::args 和 sub 调用)的解决方案(如果可能)。强制执行要容易得多perl -d:SomeMyTracer 编辑所有脚本。
    • @kobame,你说得对,他的意思是“除非”,为了完整起见,我对其进行了编辑。
    猜你喜欢
    • 2021-04-09
    • 2017-08-19
    • 2021-04-30
    • 2019-08-30
    • 2021-05-08
    • 2017-02-27
    • 2011-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多