I have a computationally expensive task in perl, and would like to inform the user that computation is ongoing by printing out a period after each portion of the computation is completed. Unfortunately, until I print a "\n", none of my periods are printed. How can I address this?
Asked
Active
Viewed 6,826 times
5 Answers
17
You need to set autoflush for STDOUT. Example:
use IO::Handle;
STDOUT->autoflush(1);
foreach (1..20) {
print '.';
sleep(1);
}

Alexandr Ciornii
- 7,346
- 1
- 25
- 29
-
2@Hans Please do not link to unauthorized copies of books. – Sinan Ünür Mar 12 '10 at 17:16
-
See http://oreilly.com/catalog/9780596003135 and http://oreilly.com/catalog/9780596003135 . – Sinan Ünür Mar 12 '10 at 17:21
-
Sorry, it just popped up when I searched the web. Now removed the link. – Hans W Mar 12 '10 at 17:49
7
set $|=1
before you start printing. Eg.
perl -e ' $|=1; foreach (1..10) { print "$_ "; sleep(1); }'

Sinan Ünür
- 116,958
- 15
- 196
- 339

Martin
- 9,674
- 5
- 36
- 36
-
@ar, `STDOUT->autoflush(1)` is the same thing as `$|=1` except `$|=1`, is global and `STDOUT->autoflush(1)` is specific to one handle. – Evan Carroll Mar 12 '10 at 17:18
-
Except you have to do a `use IO::Handle`. Not that `IO::Handle` hasn't been a standard module for eons, but ... yeah. :(` – Robert P Mar 12 '10 at 17:37
2
See the FAQ How do I flush/unbuffer an output filehandle? Why must I do this? and note:
Besides the
$|
special variable, you can usebinmode
to give your filehandle a:unix
layer, which is unbuffered ...
For the general problem, you might want to look at Time::Progress:
%b
%B
progress bar which looks like:
##############......................

Community
- 1
- 1

Sinan Ünür
- 116,958
- 15
- 196
- 339
0
What worked for me was to put the line
STDOUT->autoflush(1);
before my line
print ".";
inside my existing loop. Didn't use the sleep for fear of slowing the things down even more.

John Conde
- 217,595
- 99
- 455
- 496

ekemmler
- 1