【问题标题】:Getting all arguments passed to a subroutine as a string in Perl在 Perl 中将所有参数作为字符串传递给子例程
【发布时间】:2016-07-21 13:47:08
【问题描述】:

我正在尝试编写一个函数,该函数可以接受所有参数并将它们打印为字符串,与输入的内容完全相同。

例如使用以下函数:

test('arg1' => $arg1, 'arg2' => $arg2);

我想在函数中获取以下字符串格式化完全如下所示

"'arg1' => $arg1, 'arg2' => $arg2"

我想这样做,以便我可以打印所有参数,其方式与为调试/测试目的输入的方式相同。

【问题讨论】:

标签: string perl arguments parameter-passing subroutine


【解决方案1】:

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;

在以下程序中跟踪函数 fooBaz::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 如果你想用相同的输入对同一个函数运行多个测试,这种方法将失败。例如,对于$foo-&gt;connect(); $foo-&gt;close(); $foo-&gt;close();,您可能希望第一个close 关闭连接,但您可能希望第二个close 发出警告。不同的行为,但在您的方案中,您将拥有完全相同的测试名称。测试名称应该是描述预期行为的人类可读字符串。帮助任何未来的维护程序员(包括你自己!)并写出描述性的测试名称。
【解决方案2】:

我知道这可能不是最好的解决方案,但它确实有效:

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);

你会得到这个作为输出:

测试(时间);

【讨论】:

    猜你喜欢
    • 2021-03-09
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    • 2019-07-19
    • 1970-01-01
    • 1970-01-01
    • 2016-11-22
    • 2010-12-21
    相关资源
    最近更新 更多