Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fake input to perl's diamond operator?

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.

like image 818
bstpierre Avatar asked Jun 07 '11 13:06

bstpierre


1 Answers

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

like image 169
Mat Avatar answered Nov 10 '22 15:11

Mat