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

Hi Monks ,

Yesterday night inbetween something i tried out the following ...

The objective is : To print simple dots ( full stops ) after every one second and i did the following for that.

trial 1
#!/usr/bin/perl -w print "processing."; for($i=0;$i<=5;++$i){ print "."; sleep 1; }
the output i desired is

processing.(one second sleep).(one second sleep).(one second sleep).(one second sleep).(one second sleep).

but the output is

(5 seconds sleep)processing........

Then i tried .... trial 2
#!/usr/bin/perl -w print "processing."; for($i=0;$i<=5;++$i){ print ".\n"; sleep 1; }
This gives the output ...

processing.. (one second).

(one second).

(one second).

(one second).

(one second).

Could you please tell me where did i go wrong in sleep-ing ?

Advance thanks and regards

Prad

Replies are listed 'Best First'.
Re: sleep problem !
by rnahi (Curate) on Sep 22, 2005 at 09:50 UTC

    Your standard output needs to be unbuffered.

    Add this line before your loop:

    $|++;

    And you should get what you want.

    See Suffering from buffering (off site) for a thorough explanation.

Re: sleep problem !
by marto (Cardinal) on Sep 22, 2005 at 09:49 UTC
    Hi,

    I could be wrong but the code you have posted looks to me like your trying to achieve a progress bar.
    If this is the case then you may want to have a look at the Progress Bar modules.

    Hope this helps.

    Martin
Re: sleep problem !
by svenXY (Deacon) on Sep 22, 2005 at 09:55 UTC
    Hi,
    you need to disable output buffering by setting $| to 1

    Regards,
    svenXY
Re: sleep problem !
by gri6507 (Deacon) on Sep 22, 2005 at 13:22 UTC
    Every answer is correct. However, it may help to understand that $|++ is equivalent to
    use English; $OUTPUT_AUTOFLUSH = 1; # true
Re: sleep problem !
by Anonymous Monk on Sep 22, 2005 at 09:51 UTC
    You forgot to unbuffer the output filehandle. Add $| = 1; before printing.
Re: sleep problem !
by radiantmatrix (Parson) on Sep 22, 2005 at 14:58 UTC

    A number of people have pointed to the correct answer: auto-flush is off. No one has (yet) explained why that matters.

    With auto-flush off, your print statements will send output to the buffer; the buffer will write to the screen when it feels it is most efficient to do so (vast simplification). When you turn auto-flush on, the buffer flushes after every print, causing output to display immediately.

    It is generally good practice to localize these type of variables, as not doing so can cause unexpected behavior in modules you may use.

    { local $| = 1; ## turn on auto-flush locally print 'processing'; for (1..5) { print '.'; sleep 1; } }

    As long as I'm spouting about best practices, note my use of single quotes for strings. Generally speaking, you should use double quotes only when you need to interpolate the string (for example, print "value: $val\n";). It reduces bugs, and there's even a tiny performance benefit. Also note the for loop style I've used: C-style loops can often be avoided (and their potential for bugs along with them).

    And, marto is absolutely correct: if a progress bar is what you're after, you should definitely look into modules written for that purpose. On the terminal, my favorite is Term::ProgressBar.

    <-radiant.matrix->
    Larry Wall is Yoda: there is no try{} (ok, except in Perl6; way to ruin a joke, Larry! ;P)
    The Code that can be seen is not the true Code
    "In any sufficiently large group of people, most are idiots" - Kaa's Law
      Radian and other monks ,

      Thanks for all those superb answers. I would like to extend a specail thanks to radian as he/she took time to answer why it happens. Never will I get that doubt again.

      Well now after learning from the answer given by you people, I am eager to know without giving local $| = 1; in the following code...
      print 'processing'; for (1..5) { print ".\n"; sleep 1; }
      it works well.

      I tried it out for "\t" it does not flush . Why is such a behaviour ? what is unique about "\n"?

      rgrds

      prad
        "\n" is unique in that it finishes a line. I think it's for hysterical...errrmmm...historical reason. When something is printed on a lineprinter there is no use in printing each single char. It would last too long to open the connection, print one character, close the connection...

        So everything gets buffered until the line is full or is said to be full ("\n" sent) and then the buffer gets printed

        $\=~s;s*.*;q^|D9JYJ^^qq^\//\\\///^;ex;print