Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

print inside a loop

by nbezzala (Scribe)
on Feb 22, 2011 at 10:56 UTC ( #889564=perlquestion: print w/replies, xml ) Need Help??
nbezzala has asked for the wisdom of the Perl Monks concerning the following question:

#!/usr/bin/perl foreach my $i ( 1..3 ) { print "\nChecking something - "; sleep 3; print "OK"; } print "\n";

It prints this line all at once - "Checking something - OK"

Why does it not print "Checking something - " first, and then add "OK" after 3 seconds?

Replies are listed 'Best First'.
Re: print inside a loop
by hackman (Acolyte) on Feb 22, 2011 at 11:11 UTC
    You have to make the output unbuffered. You can do that by adding this:
    Before the loop.
    One Planet, One Internet...
    We Are All Connected...
Re: print inside a loop
by moritz (Cardinal) on Feb 22, 2011 at 11:15 UTC
Re: print inside a loop
by Ratazong (Monsignor) on Feb 22, 2011 at 11:17 UTC
    Often printing will be done immediately if you finish your text with an \n:
    print "\nChecking something - \n";
    HTH, Rata

      More specifically, when the buffering mode is set to "line-buffered" — which is the default with interactive things like terminals.

      In general, and to summarize, there are three buffering modes:

      • unbuffered — when explicitly requested, and the default for stderr
      • line-buffered — the default in interactive contexts
      • block-buffered (aka "fully buffered") — the default for everything else, like writing to files, pipes, etc.

      In block-buffered mode, flushing doesn't happen before the respective buffer, e.g. 4k bytes size, has filled up.

      For example (block-buffered):

      $ strace -ewrite perl -E 'say "X"x99 for 1..100' >/dev/null write(1, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"..., 4096) = 4096 write(1, "XXX\nXXXXXXXXXXXXXXXXXXXXXXXXXXXX"..., 4096) = 4096 write(1, "XXXXXXX\nXXXXXXXXXXXXXXXXXXXXXXXX"..., 1808) = 1808

      Without the redirect of stdout, i.e. when it's connected to the terminal, you'd see 100 write system calls 100 bytes... (line-buffered)

        Can one explicitly set buffering to line- or buffer oriented, or is that chosen by the system, and all you can do is enable/disable buffering by assigning a boolean value to $|?

        I guess the system choses, perhaps based on the -t flag, but I'm not sure at all.

Re: print inside a loop
by Khen1950fx (Canon) on Feb 22, 2011 at 11:15 UTC
    Let's give it an error to make it more interesting:
    #!/usr/bin/perl use strict; use warnings; foreach my $i ( 1..3 ) { if ($i lt 3) { print "\nChecking $i - ", "\n"; sleep 3; print "OK\n"; } else { print "\nChecking $i - ", "\n"; sleep 3; print "Not OK\n\n"; } }
    Updated: changed "something" to $i.
    Updated: Found a better unbuffered way...
    #!/usr/bin/perl use strict; use warnings; foreach my $i ( 1..3 ) { if ($i lt 3) { print "\nChecking $i - " and sleep 3 and print "OK"; } else { print "\nChecking $i - " and sleep 3 and print "Not OK\n"; } }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://889564]
Approved by Corion
Front-paged by Corion
and a moth chases the moon...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (7)
As of 2018-03-20 09:10 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (248 votes). Check out past polls.