How to fake input to perl's diamond operator?

笑着哭i 提交于 2019-12-22 02:05:22

问题


The answers to this question describe how to fake input to <STDIN>. My goal is similar to that question: my unit test needs to fake input to <>.

When I apply the same technique to fake input to <>, it doesn't work. The introductory-level explanations of <> led me to believe that it was reading from STDIN when no files are given on the command line, but this doesn't seem to be the case.

The sample I'm trying to make work:

#!/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 works, fake1 does not. A sample session (the "qwerty" is me typing):

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

fake2 line is asdf

My questions:

  1. How can I fake input to <>?
  2. What's the difference between <> and <STDIN> when no files are given on the command line? (I.e. Why does the technique in the linked question work for <STDIN> but not for <>?)

Thanks.


回答1:


Try this in your first test:

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

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

This has the disadvantage of not being "local" - no idea if you can make it local or not. (You can do that several times though, resetting before each test.)



来源:https://stackoverflow.com/questions/6265790/how-to-fake-input-to-perls-diamond-operator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!