[perl]
foreach $item (@items) {
# do something with $item
print "$item\n";
}
[/perl]
..and see my screen fill up line by line, instead of waiting untill the loop is finished and then seeing all lines at once. Does anyone know how I can do that ?
foreach $item (@items) {
# do something with $item
$stuff.="$item\n";
}
print $stuff;
The .= is the concatenation operator that adds the text to the end of the current variable. It is just another way of saying:
foreach $item (@items) {
# do something with $item
$stuff = $stuff . "$item\n";
}
You can also use it to do expressions:
$total+=12; #add 12 to $total.
$total-=5; #subtract 12 to total.
If I understand Damian correctly, that's exactly the opposite of what he wants, and gives the same result he currently sees with his own implementation.
Most likely, the problem is caused by the default stream buffering. You can cause each new text to be displayed in the browser immediately (well, to be sent to it immediately, anyway), by setting your stdout channel to unbuffered.
As even looking at Perl code gives me headaches very quickly, someone else will have to tell you how to do that in Perl... ;)
Here's what I used for a test..where urls.txt is a large file (120.000 lines). I noticed lines will be printed in chunks with or without the $¦++; , but only after the script has finished.
[perl]
#!F:\perl\bin\perl.exe
########################
$¦++;
open(FILE,"<urls.txt");
while($line = <FILE>){$lines .= $line;}
close(FILE);
@urls = "$lines";
foreach $req (@urls) {
print "URL: $req<br>";
}
exit;
[/perl]
This only used to be necessary before Apache 1.3. Is the Windows version really that outdated?
I rather suspect the broken pipe implementation in Windows. You can flush as much as you want, and the pipe will just keep buffering. I only dealt with this in C once, and I don't remember exactly what I did to fix it. One thing to try might be to set the stdout stream to binary mode. Can't garantee that this will help, but trying won't hurt... ;)
I had a lot of fun with this while trying to get a browser not to time out while doing some processing.. the following script seems to work with the following server:
Server: Apache/1.3.22 (Unix) Debian GNU/Linux PHP/4.1.1 mod_auth_pam/1.0a mod_ssl/2.8.5 OpenSSL/0.9.6c mod_perl/1.26
The script:
use CGI;$¦++;
my $q = new CGI;
print $q->header('text/plain');my $i = 99;
while ($i) {
print "$i green bottles on the wall..\n";
$i--;
sleep(1);
}
In IE 5.5 it starts displaying at 91 bottles, and works fine after that. In Mozilla 0.9.7 it starts at 98 bottles. It's running under mod_perl.. not sure if that makes a difference.
Shows you how to do all this - haven't used it myself, will have ago when I have a spare minute or two.
Note the caveat that some windows webservers don't suppport this... <snip>I think apache will be excluded as its so good ;)</snip> - not working so far
[edited]Didn't work on NT - Apache (1.3.22) - IE5.5 or Mozilla 0.9.7 - worth trying on apache linux[/edited]
I tried to run Btherl's script but both my machines seem to hang on the sleep command so I can't confirm the same behaviour on my servers yet before I look into that.
Do you have an explanation for the display timing difference Btherl ? Are the 91 or 98 lines what the machine processed in the first second before it gets to the next second, then understands the sleep command and starts printing one line per second from there on ?