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

Hi everybody!

It's probably trivial, but how can I make something printed with the print function (or maybe another function) show up on the screen instantly, before I print "\n". What I want to do is this: print a message like
I am doing something...
...time passes...
 done.
printed at the end of the previous message.

Is this possible without using modules? (I don't need cursor positioning for this.)

Thanks in advance, Lori

Replies are listed 'Best First'.
Re: simple print question
by b10m (Vicar) on Mar 26, 2004 at 15:58 UTC

    You want to use the $| variable, as described in perldoc perlvar:

           $|      If set to nonzero, forces a flush right away and
                   after every write or print on the currently
                   selected output channel.  Default is 0 (regardless
                   of whether the channel is really buffered by the
                   system or not; $| tells you only whether you've
                   asked Perl explicitly to flush after each write).
                   STDOUT will typically be line buffered if output
                   is to the terminal and block buffered otherwise.
                   Setting this variable is useful primarily when you
                   are outputting to a pipe or socket, such as when
                   you are running a Perl program under rsh and want
                   to see the output as it's happening.  This has no
                   effect on input buffering.  See "getc" in perlfunc
                   for that.  (Mnemonic: when you want your pipes to
                   be piping hot.)
    
    --
    b10m

    All code is usually tested, but rarely trusted.

      Yeah, what b10m said.

      Under normal circumstances, Perl will 'buffer' STDOUT by 'saving' writes to it until there is a whole line, and then write that line in one swoop. It does this to improve performace, but, as you are finding out, it's not what you always want.

      Hanlon's Razor - "Never attribute to malice that which can be adequately explained by stupidity"
Re: simple print question
by hardburn (Abbot) on Mar 26, 2004 at 15:59 UTC

    You're probably being bitten by buffering. Do a local $| = 1 to shut it off on the currently selected filehandle.

    ----
    : () { :|:& };:

    Note: All code is untested, unless otherwise stated

Re: simple print question
by eXile (Priest) on Mar 26, 2004 at 16:05 UTC
    I'm not sure what your question is, but I'll try to answer it. In perl you don't have to end every 'print' statement with a '\n'. If you want 'done' printed after 'I am doing something...' you do just that:
    print "I am doing something..."; print "done";
    This wil print "I am doing something...done". You have to add the '\n' if you want the rest of the text to start at the beginning of a line. For a nice effect while it's doing something you can add the dots while it's doing something:
    print "I am doing something"; for (my $i=0; $i<10; $i++) { print "."; sleep 1; #or whatever your script is doing } print "done";
      I knew that, but the problem was that Perl is buffering the output, as the other guys said. So I was getting what I wanted, but not when I wanted. To put it simple, the first part showed up only when the second part was printed too, and I didn't get the desired effect.

      But the $| = 1 trick solves the problem... thanks guys!

Re: simple print question
by Happy-the-monk (Canon) on Mar 26, 2004 at 15:56 UTC

    like this?

    print "I am doing something..."; # no "\n" here. sleep $time_passes; print " done\n"