我正在寻找调试从命名空间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 "$subn";
# &$sub;
#}
1;
并寻找一种方法如何使用sub
调用从Myapp::*
的命名空间打印被调用sub
的实际参数。
或者这里有一些更简单(通用)的方法来
- 合并执行线跟踪器
DB::DB
- 使用每个子例程调用参数的转储(及其返回值,如果可能)?
我不知道它是否在任何理智的含义中算作"更容易",但您可以遍历符号表并将所有函数包装在打印其参数和返回值的代码中。下面是如何完成的示例:
#!/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);