Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Well, yet another newbie question:
print "go to sleep... "; sleep 5; print "woke up.";
If I run this code, it will sleep first, then print 'go to sleep', then 'woke up'. Why?

Thank You,
nixter

Replies are listed 'Best First'.
Re: print sleep print
by Beatnik (Parson) on Jun 26, 2001 at 16:43 UTC
    try :
    #!/usr/bin/perl -w $|++; print "foo"; sleep 5; print "bar";
    and check perlvar for the elaborate meaning of $|... being the autoflush var.

    Greetz
    Beatnik
    ... Quidquid perl dictum sit, altum viditur.
Re: print sleep print
by Sifmole (Chaplain) on Jun 26, 2001 at 16:53 UTC
    Just to elaborate, and fill in a little bit on what Masem and Beatnik said...

    The print, sleep, print is occuring when you expect it too. However, output is buffered -- meaning that what get sent to output get held until the buffer gets flushed.

    The $| = 1; line tells Perl to shut off its buffering; So everything that gets printed goes out immediately.

      The $| = 1; line tells Perl to shut off its buffering;

      A bit of a nit, but Perl isn't doing the buffering and setting $|=1 doesn't turn off any buffering. C's stdio library is doing the buffering and $|=1 tells Perl to issue an fflush() after each statement that writes to that file handle (the output handle that was selected when $| was modified).

      Some consequences of this are that STDERR is (at least usually) not buffered even though:

      select(STDERR); print $|;
      prints "0" by default. Also, STDOUT is usually "line buffered" when going to an interactive terminal (the buffer gets flushed by the C RTL whenever a newline is found) but is usually "block buffered" (a fixed-length buffer is used and data is only flushed to the file when that buffer fills) when redirected to a file.

              - tye (but my friends call me "Tye")
        Note that typically if STDOUT is connected to an interactive terminal, a read from STDIN causes the buffer to STDOUT to be flushed.
        #!/usr/bin/perl -w print ">>>> "; sleep 3; <>; __END__
        Only after 3 seconds, the ">>>> " appears.

        -- Abigail

        I suspected that it had something to do with buffering.
        The  $| = 1; worked in my little example. I guess it'll work in the rest of my scripts, too.
        Thanks everybody for the help.
        nixter
Re: print sleep print
by Masem (Monsignor) on Jun 26, 2001 at 16:40 UTC
    You need to add a "\n" to the end of the print statements; most terminals will not print a line until they get a carriage return (\n), so the terminal doesn't print anything until the perl program is completed since it's all on one line.


    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain