2011-07-02 15 views
15

Hoy en mi universidad un profesor me hizo una pregunta. Escribió este código en el papel y dijo "¿Cuál será el resultado de este código?"¿Por qué no imprimir nada en cada iteración de un ciclo cuando uso sleep?

use warnings; 

for (1 .. 20) 
{ 
    print "."; 
} 

me resultó fácil y dicho que va bucle 20 veces y en cada iteración se imprimirá un punto (.) Y por lo tanto un total de 20 puntos será la salida.

Dijo que tiene razón y luego hizo algunos cambios en el código. El código era:

use warnings; 

for (1 .. 20) 
{ 
    print "."; 
    sleep 1; 
} 

Dijo cuál sería el resultado ahora? No sabía acerca de la función de dormir, supongo que en cada iteración imprimirá el punto (.) Y luego esperará durante 1 segundo (debido a la función de reposo) y luego repetirá y luego lo repetirá. imprimir (.) luego esperará durante 1 segundo y así sucesivamente ...

El maestro me dijo que lo revisara en casa. Lo probé en casa y supe que el segundo código espera 20 segundos y luego imprime todos los puntos (20 puntos) a la vez. Quiero saber cómo sucedió esto? ¿Por qué no se imprime el punto (.) En cada iteración?

Respuesta

24

El verdadero problema no tiene nada que ver con sleep, sino más bien que ............

Usted es Suffering from Buffering. El enlace proporcionado lo lleva a un excelente artículo de The Perl Journal circa 1998 de Marc Jason Dominus (el autor de Higher-Order Perl). El artículo puede tener más de una década, pero el tema es tan relevante hoy como lo fue cuando lo escribió.

Otros han explicado la técnica $| = 1;. Me gustaría añadir a aquellos comentarios que en el pensamiento predominante de la comunidad Perl parece ser que $| = 1 es preferible a $|++ simplemente porque es más claro en su significado. Lo sé, el autoincrement también es bastante simple, pero todos los que alguna vez mirarán tu código conocen el comportamiento de $| cuando se aplican ++ o -- (sin buscarlo en perlvar). También prefiero localizar cualquier modificación de las "variables especiales" de Perl para que los efectos no se trasladen a otras partes del código que pueden no ser agradables con un cambio particular en el comportamiento predeterminado de Perl. Para que ese sea el caso, lo escribiría como:

use strict; 
use warnings; 

{ 
    local $| = 1; 
    for (1 .. 20) { 
     print '.'; 
     sleep 1; 
    } 
} 
+0

Gracias por remitir el artículo. :) –

+1

'$ | --' alterna el valor entre' 0' y '1', y' $ | ++ 'establece' $ | 'en' 1' (incluso si está precedido por '$ | = -1;') De hecho, desalentó el uso de tales características oscuras. – ikegami

15

Perl, y muchos otros programas, salida del buffer de línea por defecto. Puede configurar $| en 1 si necesita resultados sin búfer.

12

No está borrando el búfer. Si hay una nueva línea al final de la instrucción de impresión lo hará automáticamente por usted:

use warnings; 

for (1 .. 20) { 
    print ".\n"; 
    sleep 1; 
} 

Si no desea que la nueva línea (no me imagino que lo hacen) se puede utilizar el autoflush especial variable $|. Intente configurarlo en 1 o incrementándolo.

use warnings; 

$|++; 

for (1 .. 20) { 
    print "."; 
    sleep 1; 
} 
Cuestiones relacionadas