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

OK, all yoos monks gave me some great insight on my quest for wisdom. Here's one that should be much easier.

When I look into using $| to flush STDOUT, I find stuff like this:

$old_handle = select (STDOUT); $| = 1; # perform flush after each write to STDOUT select ($old_handle); # restore previously selected handle

Why do I have to do all that selecting of file handles? If STDOUT is already selected by default, and I'm not changing to another handle, can't I just use:

$| = 1; print "some stuff\n"; print "some more stuff\n"; $| = 0;
What I'd really rather do is just flush STDOUT at will. But if theres a flush(STDOUT) function, I haven't seen it documented.

I now humbly await your monkitudinous wisdom.

Replies are listed 'Best First'.
Re: Lowering my STDards :)
by hossman (Prior) on Jun 29, 2007 at 20:55 UTC
    Why do I have to do all that selecting of file handles? If STDOUT is already selected by default, and I'm not changing to another handle, can't I just use...

    Yes, presuming you know beyond a shadow of a doubt that STDOUT is already selected. The code you quoted takes care of the possibility that STDOUT is not the currently selected handle, but that you want to to autoflush STDOUT regardless of which handle is currently selected

    But if theres a flush(STDOUT) function, I haven't seen it documented

    Functions that take Handles as arguments tend to be very perl4esque, and not many have been added in a while. There is a more OO mechanism for dealing with handles in the IO::Handle class, which includes an flush method...

    my $io = IO::Handle->new_from_fd(fileno(STDOUT),"w")) ... $io->print(...); ... $io->flush(); ...
Re: Lowering my STDards :)
by FunkyMonk (Bishop) on Jun 29, 2007 at 20:07 UTC
    Yes, $|=1 will autoflush STDOUT on every write. localising within a block is the more common Perl idiom rather than using $|=1; print "..."; $|=0:

    { local $| = 1; print "hi"; }

    See perlvar for more on $|.

Re: Lowering my STDards :)
by msk_0984 (Friar) on Jun 30, 2007 at 06:45 UTC
    Yaah as the monks said its absolutly true. But as a brief to explain about it in detail .....

    When you send output to a file using print or write, the operating system might not write it right away. Some systems first send the output to a special array known as a buffer; when the buffer becomes full, it is written all at once. This process of output buffering is usually a more efficient way to write data.

    In some circumstances, you might want to send output straight to your output file without using an intervening buffer. (For example, two processes might be sending output to the standard output file at the same time.) The $| system variable indicates whether a particular file is buffered. By default, the Perl interpreter defines a buffer for each output file, and $| is set to 0. To eliminate buffering for a particular file, select the file and then set the $| variable to a nonzero value. For example, the following code eliminates buffering for the MYFILE output file:

    select ("MYFILE"); $| = 1;

    These statements set MYFILE as the default output file and then turn off buffering for it.

    Work Hard Party Harderrr!!
    Sushil Kumar
Re: Lowering my STDards :)
by Anonymous Monk on Jul 02, 2007 at 15:28 UTC
    Here's a one-line sample from my Mplayer control script:

    select((select($scr[$po]), $| = 1)[0]);  #damn buffering...

    You would probably want:

    select((select(STDOUT), $| = 1)[0]);
      The easiest way is this: use IO::Handle; ... print "Some text that would be buffered since it does not contain newline"; STDOUT->flush();