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

I'm stuck with getting the STDOUT buffer to flush for a web app i'm writing. here's the issue:

i have a script that instantiates display objects, then prints out the results. let's call it index.cgi

index.cgi basically does this:

my $page = DisplayModule->new(); my $html = $page->build_page; print $page;
not much processing there.

the display module makes some decisions about what page to build, then build them, collecting all of the HTML ( to be later printed by index.cgi )

one of the methods in DisplayModule ( that gets called by the build_page routine ) needs to print some 'status messages' out to the screen before the HTML is rendered. but the print statements live in another module, let's call it Debugger.pm

so in DisplayModule->build_page, an new Debugger is created. something like this:

sub build_page { my $self = shift; #### the usual arg processing, etc my $debug = Debugger->new(); $debug->debug_it(); ### gather up more info, stick it into the $html var return $html; }
but none of these give me the desired behavior -- status messages on STDOUT ( the client browser ) while the html is being gathered by the rest of the program.

is there something i'm overlooking?

Replies are listed 'Best First'.
Re: unbuffering I/O with objects
by dws (Chancellor) on Mar 23, 2001 at 10:05 UTC
    The behavior you desire is not supported. A browser does not behave like a terminal. You can't just "print" to it and have things show up in sequential order.

    If you're trying to get "status" messages out to the browser before the HTML (and after you've printed the Content-type: header), one option is to print the status messages as HTML comments, then examine the resulting source to see the status messages. The resulting source would look like

    <!-- status: input buffers are out of cheese --> <!-- status: rendering algorithm is full of fleas --> <html> ... </html>

    Now if your purpose it to show a temporary message on the browser while you perform some longer operation that'll result later in a page of HTML, merlyn just happens to have an article that shows one way to do it.

    Update: I should have said "not universally supported." It's true that some browsers can be coaxed into printing text that appears outside of <html>..</html> tags, but any solution that depends on this is neither horizontally portable (across browsers) or temporally portable (across new browser releases).

      i hate to say anything nice about M$ products -- but IE ( 5.0 ) gives me the behavior i want - Netscape ( 4.73 ) doesn't.

      and it can be done -- it's a matter of manipulating the way the browser performs its rendering tasks.

      update: i checked Mozilla's rendering, and it performs as desired as well.

      so it's a matter of getting Netscape to cooperate

        A standard browser is not required to "partially render" a page. The fact that some browsers try to make sense of the input stream as seen so far is merely gravy. It's not that Netscape 4 is deficient—it's that some other browsers are trying to be uber-friendly.

        -- Randal L. Schwartz, Perl hacker