perlmeditation
broquaint
<b>"Perl Idioms Explained" explained</b>
<p/>
This is the first post in a series of posts that aim to explain the workings and
reasoning behind common perl idioms. Each post will be relatively short but
hopefully informative enough to sufficiently illuminate each idiom.
<p/>
<b>Perl Idioms Explained - $|++</b>
<p/>
<code>
use strict;
use warnings;
$|++;
use Some::Module 'process_stuff';
print '.' while process_stuff();
</code>
It is not entirely uncommon to see this rather mysterious combination of
characters following the usual pragma declarations - <tt>$|++</tt>. The most
perfunctory glance will reveal that the post-increment operator is used, and a
further look will show that said operator is working on the <tt>$|</tt>.
Browsing through <tt>[perlman:perlvar|man perlvar]</tt> we see that
<tt>$|</tt> is defined like so
<p/>
<tt>
autoflush HANDLE EXPR<br/>
$OUTPUT_AUTOFLUSH<br/>
$|
<blockquote>
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 the getc entry in the perlfunc manpage for
that. (Mnemonic: when you want your pipes to be piping hot.)
</blockquote>
</tt>
<p/>
So the the post-increment on the <tt>$|</tt> sets it to 1 (sidenote - its
value, magically, can only ever be 0 or 1) which will turn <i>off</i> buffering
for <tt>STDOUT</tt>. The implications for turning off buffering are
far reaching so if you'd like to know more about it then see [Dominus]'
cracking [http://perl.plover.com/FAQs/Buffering.html|Suffering from Buffering].
For a simple demonstration of this idiom in action and the effects of output buffering
try running the following piece of code
<code>
print "printing dots with buffering\n";
select undef, undef, undef, 0.25 or print '.'
for 1 .. 10;
print "\nflush forced\n";
$|++;
print "printing dots without buffering\n";
select undef, undef, undef, 0.25 or print '.'
for 1 .. 10;
print "\nflush forced\n";
</code>
When that is run you should notice that <i>with</i> buffering the dots aren't
displayed until the flush is forced with a <tt>\n</tt>, whereas <i>without</i>
buffering the dots were displayed immediately as the output wasn't being held in
an output buffer.
<p/>
<b>Summary</b>
<p/>
The <tt>$|++</tt> idiom will turn buffering <i>off</i> for when we want to see
our output, and we want to see it now!
<p/>
<tt>_________<br><u>broquaint</u></tt>