【问题标题】:How to fake input to perl's diamond operator?如何伪造 perl 的钻石运算符的输入?
【发布时间】:2011-09-10 01:58:57
【问题描述】:

The answers to this question 描述如何伪造<STDIN> 的输入。我的目标与那个问题类似:我的单元测试需要伪造<> 的输入。

当我对<> 的虚假输入应用相同的技术时,它不起作用。 <> 的介绍性解释让我相信,当命令行上没有给出文件时,它是从 STDIN 读取的,但情况似乎并非如此。

我正在尝试制作的示例:

#!/usr/bin/perl -w

use strict;
use warnings;
use Carp;
use English qw( -no_match_vars );

sub fake1 {
    my $fakeinput = "asdf\n";
    open my $stdin, '<', \$fakeinput
      or croak "Cannot open STDIN to read from string: $ERRNO";
    local *STDIN = $stdin;

    my $line = <>;
    print "fake1 line is $line\n";

    return 0;
}

sub fake2 {
    my $fakeinput = "asdf\n";
    open my $stdin, '<', \$fakeinput
      or croak "Cannot open STDIN to read from string: $ERRNO";
    local *STDIN = $stdin;

    my $line = <STDIN>;
    print "fake2 line is $line\n";

    return 0;
}

fake1();
fake2();

fake2 有效,fake1 无效。一个示例会话(“qwerty”是我输入的):

$ perl /tmp/diamond.pl
qwerty
fake1 line is qwerty

fake2 line is asdf

我的问题:

  1. 如何伪造&lt;&gt; 的输入?
  2. 在命令行没有给出文件时&lt;&gt;&lt;STDIN&gt;有什么区别? (即为什么链接问题中的技术适用于&lt;STDIN&gt;,但不适用于&lt;&gt;?)

谢谢。

【问题讨论】:

  • 仔细阅读 perlop 的文档(I/O operators),看起来&lt;&gt; 使用了魔法。那里有一个修改@ARGV 的相关示例,但我不确定我的测试能否可靠地保证它是&lt;&gt; 的第一个实例,或者修改@ARGV 是安全的。
  • 我不明白为什么不直接使用local @ARGV = ...
  • @tchrist - 这将如何运作?

标签: perl unit-testing io diamond-operator


【解决方案1】:

在你的第一个测试中试试这个:

open ARGV, '<', \$fakeinput
      or croak "Cannot open STDIN to read from string: $ERRNO";

my $line = <>;
print "fake1 line is $line\n";

这具有不是“本地”的缺点 - 不知道您是否可以将其设为本地。 (不过,您可以多次这样做,每次测试前重置。)

【讨论】:

  • 完美。事实上,我只需要更改local *ARGV = $stdin;。谢谢!手册中的关键似乎是“ 只是 的同义词,这很神奇。” (“神奇”的部分让我有点害怕,但它似乎暂时起作用了。)
  • 其实&lt;&gt;readline( *ARGV );的简写。详情请见perldoc -f readline
猜你喜欢
  • 1970-01-01
  • 2021-01-02
  • 1970-01-01
  • 2016-08-15
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
  • 2011-02-23
相关资源
最近更新 更多