Beefy Boxes and Bandwidth Generously Provided by pair Networks DiBona
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

print problem

by Punto (Scribe)
on Dec 21, 2001 at 01:04 UTC ( [id://133694]=perlquestion: print w/replies, xml ) Need Help??

This is an archived low-energy page for bots and other anonmyous visitors. Please sign up if you are a human and want to interact.

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

Hi..

I have a loop that does a sleep(1); and then a number of calculations, and then I display the results like this:

print "$result1 - $result2 - $result3\r";

I'm using \r because I want it to be overwritten on the next print, but it doesn't print anything.. if I change to \n, it works fine.. Do I have to flush a buffer or something?

Thanks..

Replies are listed 'Best First'.
Re: print problem
by {NULE} (Hermit) on Dec 21, 2001 at 01:45 UTC
    Hi Punto,

    Yes, is the short answer to your question. Here is some code that works:

    #! /usr/bin/perl -w use strict; $| = 1; # This forces your selected filehandle (STDOUT # in this case) to be unbuffered. my $i = 0; while (1) { sleep(1); print $i++," - ",$i++," - ",$i++,"\r"; }

    There are other ways to do this that might be more elegant or more cross-platform. I believe that looking on CPAN for Term and Curses might be useful to you. (Note to self: finish up that stinking Curses tutorial already...)

    Good luck,
    {NULE}
    --
    http://www.nule.org

      The reason you need to set $| is explained 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
                ...
                STDOUT will typically be line buffered if output
                is to the terminal and block buffered otherwise.
                ...
      
      So in your orriginal program, the buffer was just building up because it never say a line termination. (and when you switched to "\n" it did).
Re: print problem
by mr_mischief (Monsignor) on Dec 21, 2001 at 02:39 UTC
    The most accurate short answer is maybe.

    On Linux Mandrake 8.0 through PuTTY and on Windows 98 SE with ActiveState build 623 I didn't need to flush buffers doing something similar. Different term types on different systems will do different things with the code I used. Considering the problem you are having, I'd say flushing buffers is a good idea. The $| variable is probably your very best bet, although the Term modules, Curses module, or possibly a few other things could help. I won't mention the other things, because using the three I already mentioned should be more than enough to get the job done and are widely used. There are, in the Perl spirit, even more ways to do it, but you probably will never need to use them. ;-)

    Just in case you're curious, here's the Linux test code I used:
    perl -e 'for (a..fred) { print "$_\r" } print "\n"'
    ...and here's the Windows 98 code:
    perl -e "for (a..f) { sleep 1; print qq{$_\r} } print qq{\n};"
    or
    perl -e "for (a..fred) { print qq{$_\r} } print qq{\n};"
Re: print problem
by Foo::Bar (Acolyte) on Dec 21, 2001 at 06:06 UTC
    All good solutions but there is another way to do it...
    use FileHandle; STDOUT->autoflush(1);
    Should solve the problem also...
Re: print problem
by dmmiller2k (Chaplain) on Dec 21, 2001 at 15:43 UTC

    I won't pick nits about whether this makes STDOUT unbuffered, or merely behave as though it were unbuffered (yes, there is a difference), but in the spirit of T M T O W T D I:

    $|=1;

    is exactly equivalent to:

    use English; $OUTPUT_AUTOFLUSH=1;

    which is effectively the same as:

    use FileHandle; STDOUT->autoflush(1);

    It all boils down to how much typing you're up for vs. whether or not you'll remember what it means later.

    dmm

    You can give a man a fish and feed him for a day ...
    Or, you can
    teach him to fish and feed him for a lifetime

      except that (unless you are going to use them elsewhere)

      use English;  ...and...
      use FileHandle;

      both drag in a pile more (mostly useless) code... isn't

      $| = 1; #set autoflush on

      good enough?

        English isn't that bad. It could be made a little skimpier, though. Maybe I'll fix up its import slightly. Thanks for the idea!
Re: print problem
by k2 (Scribe) on Dec 22, 2001 at 11:17 UTC
    Hello! I do almost the same thing, in my case it's at "status bar"
    printing how many lines my script has read from a file.
    In my case I start by printing the "\r". Otherwise
    you print you results and the emediatly erase them.
    So without having tested this I think
     print "\r$result1 - $result2 - $result3";
    will work.
    /k2

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://133694]
Approved by root
help
Sections?
Information?
Find Nodes?
Leftovers?
    Notices?
    hippoepoptai's answer Re: how do I set a cookie and redirect was blessed by hippo!
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.