Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

print inside a loop

by nbezzala (Scribe)
on Feb 22, 2011 at 10:56 UTC ( [id://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:
    $|=1;
    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
      Often...

      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?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://889564]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (6)
As of 2024-04-23 09:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found