2011-06-07 58 views
13

The answers to this question描述如何僞造輸入到<STDIN>。我的目標類似於這個問題:我的單元測試需要僞造輸入到<>如何僞造perl的鑽石操作員的輸入?

當我將相同的技術應用到<>的假輸入時,它不起作用。對於<>的入門級解釋讓我相信,當它在命令行上沒有文件時,它是從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. 我哪有假輸入<>
  2. 當命令行中沒有文件時,<><STDIN>之間有什麼區別? (也就是說,爲什麼鏈接問題中的技術適用於<STDIN>而不適用於<>?)

謝謝。

+0

閱讀perlop的文檔(在[I/O操作符](http://perldoc.perl.org/perlop.html#I%2fO ) - 更仔細的看起來像'<>'使用魔法。有一個相關的例子修改'@ ARGV',但我不確定我的測試能夠可靠地保證它是'<>'的第一個實例,或者修改'@ ARGV'是安全的。 – bstpierre 2011-06-07 13:38:31

+0

我不明白爲什麼不使用'local @ARGV = ...'。 – tchrist 2011-06-07 18:53:14

+0

@tchrist - 這將如何工作? – bstpierre 2011-06-08 02:26:15

回答

9

在第一個測試試試這個:

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

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

這已經不是「本地」的缺點 - 不知道,如果你可以把它本地的。 (你可以做幾次,但是在每次測試之前重置)

+2

完美。實際上,我需要改變的只有'local * ARGV = $ stdin;'。謝謝!手冊中的關鍵詞似乎是「<>」,它只是的同義詞,這很神奇。「 (這個「神奇」的部分讓我感到有點恐懼,但它似乎目前正在工作。) – bstpierre 2011-06-07 13:44:14

+2

實際上''''是readline(* ARGV);'的縮寫。有關詳細信息,請參閱'perldoc -f readline'。 – shawnhcorey 2011-06-07 16:21:40