【问题标题】:How do I expand variables in Perl readpipe handlers?如何在 Perl 读取管道处理程序中扩展变量?
【发布时间】:2012-06-14 06:32:35
【问题描述】:

似乎反引号中的变量在传递给 readpipe 函数时没有展开。如果我重写了 readpipe 函数,如何扩展变量?

BEGIN {
*CORE::GLOBAL::readpipe = sub {print "Run:@_\n"};
}

`ls /root`;
my $dir = "/var";
`ls $dir`;

运行此命令:

Run:ls /root
Run:ls $dir

我正在尝试模拟对我正在编写的测试代码的外部调用。如果某个地方有一个 CPAN 模块可以帮助解决所有这些问题,那也会有所帮助。

更新

我决定使用一个非常丑陋的解决方法来解决我的问题。事实证明,使用 readpipe() 而不是反引号可以正确扩展变量。我在运行测试之前使用了一个自动脚本清理器,它在运行测试之前将所有反引号转换为readpipe()

例如跑步:

$ cat t.pl

BEGIN {
    *CORE::GLOBAL::readpipe = sub {print "Run:@_\n"};
}

`ls /root`;
my $dir = "/var";
`ls $dir`;
readpipe("ls $dir");

给予:

$ perl t.pl
Run:ls /root
Run:ls $dir
Run:ls /var

不过,我仍在寻找更清洁的解决方案。

【问题讨论】:

    标签: perl unit-testing backticks


    【解决方案1】:

    这似乎是 Perl 中的一个错误。使用perlbug举报。

    【讨论】:

      【解决方案2】:

      您可能想改用IPC::Run

      use IPC::Run 'run';
      
      run [ "ls", $dir ], ">", \my $stdout or die "Cannot run - $!";
      

      或者如果您不想捕获输出,system() 可能会更好

      system( "ls", $dir ) == 0 or die "Cannot system - $!";
      

      【讨论】:

      • 感谢模块参考。然而,我正在寻找一种简单的方法来模拟像反引号和 system() 这样的系统调用来运行我对遗留代码的单元测试。
      • @SandipBhattacharya 我确定我不理解这个问题。 backticks 和 exec 不会返回任何输出,而 system 会返回。 eval 和 qx 是否符合要求?
      • @shinronin 我正在尝试覆盖/模拟现有遗留代码中的反引号,以便我可以安全地测试它们。虽然我可以替换 *CORE::GLOBAL::readpipe 来模拟反引号,但在参数包含要扩展的变量的情况下它们不起作用。由于反引号和readpipe() 之间的这种不一致的行为,很难模拟这样的代码。我不是在尝试编写新代码。如果我这样做了,我会使用 readpipe() 而不是反引号,以便我可以根据需要模拟代码。
      • @shinronin:你说错了;反引号 do 提供输出,而 system() 是静默的,exec 不能返回输出(因为调用它的进程被替换了)。
      • @jeffbragg 哎呀,真的。我永远无法让他们保持笔直。 perldoc -f 是一个不变的伴侣。 ;-)
      猜你喜欢
      • 2016-06-29
      • 2012-06-01
      • 2023-03-11
      • 1970-01-01
      • 2021-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多