2011-07-02 17 views
15

Dzisiaj w mojej szkole nauczyciel zadał mi pytanie. Napisał ten kod na papierze i powiedział: "Jaki będzie wynik tego kodu?"Dlaczego nie drukuje się niczego na każdej iteracji pętli, kiedy używam trybu uśpienia?

use warnings; 

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

Okazało się, że jest łatwy i że nie będzie pętli 20 razy, a w każdej iteracji będzie drukowania kropek (.), A zatem ogółem 20 punktów będzie wyjściowego.

Powiedział, że masz rację, a następnie wprowadził pewne zmiany w kodzie. Kod był:

use warnings; 

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

Powiedział, co będzie teraz wyjście? Nie wiedziałem o funkcji spania, domyśliłem się, że przy każdej iteracji będzie drukować kropkę (.), A następnie będzie czekać 1 sekundę (ze względu na funkcję spania), a następnie ponownie będzie iterować, a następnie znowu będzie wydrukuj (.) wtedy poczeka na 1 sekundę i tak dalej ...

Nauczyciel kazał mi sprawdzić to w domu. Próbowałem go w domu i dowiedziałem się, że drugi kod czeka 20 sekund, a następnie drukuje wszystkie kropki (20 kropek) na raz. Chcę wiedzieć, jak to się stało? Dlaczego kropka (.) Nie jest drukowana na każdej iteracji?

Odpowiedz

24

Prawdziwym problemem nie ma nic wspólnego z sleep, ale raczej, że ............

Jesteś Suffering from Buffering. Podany link przeniesie Cię do doskonałego artykułu z Perl Journal ok. 1998 r. Od Marca Jason'a Dominusa (autora książki Higher-Order Perl). Artykuł może mieć ponad dekadę, ale temat jest dziś równie aktualny, jak w chwili jego napisania.

Inni wyjaśnili technikę $| = 1;. Chciałbym dodać do tych komentarzy, że w dominującym myśleniu społeczności Perla wydaje się, że $| = 1 jest lepsze od $|++ tylko dlatego, że jest jaśniejsze w swoim znaczeniu. Wiem, że autoinkodowanie jest również bardzo proste, ale czy wszyscy, którzy kiedykolwiek zobaczą Twój kod, będą znać zachowanie $|, gdy zostaną zastosowane (nie szukając ich w perlvar). Zdarzają mi się również wolą lokalizować dowolne modyfikacje "specjalnych zmiennych" Perla, aby efekty nie przenikały do ​​innych części kodu, które mogą nie być miłe z konkretną zmianą domyślnego zachowania Perla. W związku z tym, napiszę to jako:

use strict; 
use warnings; 

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

Dzięki za odesłanie artykułu. :) –

+1

'$ | -" przełącza wartość pomiędzy '0' i' 1', a '$ | ++' ustawia '$ |' na '1' (nawet jeśli poprzedza ją' $ | = -1; '). Rzeczywiście zniechęcam do korzystania z takich niejasnych funkcji. – ikegami

15

Perl, i wiele innych programów, domyślnie wyjście linii-bufora. Możesz ustawić $| na 1, jeśli potrzebujesz niebuforowanego wyjścia.

12

Nie kasuje bufora. Jeśli tam jest znak nowej linii na końcu instrukcji print to zrobi to za Ciebie automatycznie:

use warnings; 

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

Jeśli nie chcą nowej linii (nie wyobrażam sobie zrobić) można użyć specjalnego autoflush zmienna $|. Spróbuj ustawić go na 1 lub zwiększając go.

use warnings; 

$|++; 

for (1 .. 20) { 
    print "."; 
    sleep 1; 
} 
Powiązane problemy