我正在尝试编写一个函数,该函数可以将所有参数作为字符串输入,并将它们打印为完全一样的字符串。在Perl中将所有传递给子例程的参数作为字符串获取
例如使用以下功能:
test('arg1' => $arg1, 'arg2' => $arg2);
我想获得格式化EXACTLY功能内的以下字符串所看到如下:
"'arg1' => $arg1, 'arg2' => $arg2"
我想这样做,我可以打印所有参数,就像输入用于调试/测试目的一样。
我正在尝试编写一个函数,该函数可以将所有参数作为字符串输入,并将它们打印为完全一样的字符串。在Perl中将所有传递给子例程的参数作为字符串获取
例如使用以下功能:
test('arg1' => $arg1, 'arg2' => $arg2);
我想获得格式化EXACTLY功能内的以下字符串所看到如下:
"'arg1' => $arg1, 'arg2' => $arg2"
我想这样做,我可以打印所有参数,就像输入用于调试/测试目的一样。
Perl提供了特殊的debugging hooks,可让您看到已编译源文件的原始行。您可以编写一个自定义调试器,每次调用子例程时都会打印原始行。
以下内容可让您指定一个或多个要匹配的子例程;每次调用一个匹配的子程序时,都会打印相应的行。
package Devel::ShowCalls;
our %targets;
sub import {
my $self = shift;
for (@_) {
# Prepend 'main::' for names without a package specifier
$_ = "main::$_" unless /::/;
$targets{$_} = 1;
}
}
package DB;
sub DB {
($package, $file, $line) = caller;
}
sub sub {
print ">> $file:$line: ",
${ $main::{"_<$file"} }[$line] if $Devel::ShowCalls::targets{$sub};
&$sub;
}
1;
要跟踪的在下面的程序功能foo
和Baz::qux
调用:
sub foo {}
sub bar {}
sub Baz::qux {}
foo(now => time);
bar rand;
Baz::qux(qw/unicorn pony waffles/);
运行:
$ perl -d:ShowCalls=foo,Baz::qux myscript.pl
>> myscript.pl:5: foo(now => time);
>> myscript.pl:7: Baz::qux(qw/unicorn pony waffles/);
注意,这将只打印的第一行调用,所以它不适用于像
foo(bar,
baz);
唯一的问题是我想用它来编写单元测试脚本。基本上,我希望我的测试都以相关的函数和参数命名,这样我就不需要手动命名每个测试。有没有办法做到这一点,而不是在调试模式下显式运行Perl?或者可能从测试脚本本身调用调试模式? – tjwrona1992
@ tjwrona1992如果你想用相同的输入对同一个函数运行多个测试,那么这种方法就会失败。例如,使用'$ foo-> connect(); $ foo->接近(); $ foo-> close();',你可能希望第一个'close'关闭连接,但你可能想要第二个'close'来警告。不同的行为,但在你的计划中,你将拥有两个完全相同的测试名称。测试名称应该是描述预期行为的人类可读字符串。做任何未来的维护程序员(包括你自己!)的帮助,并写出描述性测试名称。 – ThisSuitIsBlackNot
我知道这可能不是最好的解决方案,但它的工作原理:
sub test {
my (undef, $file_name, $line_number) = caller;
open my $fh, '<', $file_name or die $!;
my @lines = <$fh>;
close $fh;
my $line = $lines[$line_number - 1];
trim($line);
print $line."\n";
}
sub trim {
return map { $_ =~ s/^\s+|\s+$//g } @_;
}
现在,当你运行这个命令:
test(time);
你会得到这样的输出:
测试(时间);
另一个例子:假设你想做'测试(时间)'。只需打印“@ _”将打印当前时间的纪元值,并且它非常不清楚(乍一看)您正在测试当前时间。 – tjwrona1992
使用[Devel :: Trace](https://metacpan.org/pod/Devel:Trace),或者只是使用普通的调试器并在函数被调用的那一行中断。 – ThisSuitIsBlackNot
参见['Debug :: Show'](https://metacpan.org/pod/Debug::Show),['PadWalker'](https://metacpan.org/pod/PadWalker),['Data :: Dumper :: Names'](https://metacpan.org/pod/Data::Dumper::Names),['Data :: Dumper :: Lazy'](https://metacpan.org/pod/ Data :: Dumper :: Lazy)和['Debug :: ShowStuff :: ShowVar'](https://metacpan.org/pod/Debug::ShowStuff::ShowVar) –