2011-06-07 20 views
13

The answers to this question describe cómo falsificar la entrada a <STDIN>. Mi objetivo es similar a esa pregunta: mi unidad de prueba necesita una entrada falsa a <>.¿Cómo falsificar la entrada al operador de diamantes de perl?

Cuando aplico la misma técnica a la entrada falsa a <>, no funciona. Las explicaciones de nivel introductorio de <> me llevaron a creer que estaba leyendo de STDIN cuando no se da ningún archivo en la línea de comandos, pero este no parece ser el caso.

La muestra que estoy tratando de hacer el trabajo:

#!/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 obras, fake1 no. Un ejemplo de sesión (el "qwerty" me está escribiendo):

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

fake2 line is asdf 

Mis preguntas:

  1. Cómo puedo entrada falsa para <>?
  2. ¿Cuál es la diferencia entre <> y <STDIN> cuando no se proporcionan archivos en la línea de comandos? (Es decir, ¿Por qué la técnica en cuestión el trabajo vinculado para <STDIN> pero no para <>?)

Gracias.

+0

Lectura de la documentación para perlop (en [operadores de E/S] (http://perldoc.perl.org/perlop.html#I%2fO) -Operators)) con más cuidado, parece que '<>' usa magia. Hay un ejemplo relevante allí que modifica '@ ARGV', pero no estoy seguro de que mi prueba pueda garantizar de manera confiable que es la primera instancia de' <> ', o que la modificación de' @ ARGV' es segura. – bstpierre

+0

No entiendo por qué no usar 'local @ARGV = ...'. – tchrist

+0

@tchrist - ¿Cómo funcionaría eso? – bstpierre

Respuesta

9

Pruebe esto en su primera prueba:

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

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

Esto tiene la desventaja de no ser "local" - ni idea de si se puede hacer que sea local o no. (Sin embargo, puede hacer eso varias veces, restablecer antes de cada prueba).

+2

Perfecto. De hecho, todo lo que necesitaba cambiar era 'local * ARGV = $ stdin;'. ¡Gracias! La clave del manual parece ser "<> es solo un sinónimo de , que es mágico". (La parte "mágica" me asusta un poco, pero parece estar funcionando por el momento.) – bstpierre

+2

En realidad, '<>' es la abreviatura de 'readline (* ARGV);'. Ver 'perldoc -f readline' para más detalles. – shawnhcorey

Cuestiones relacionadas