Re: What the heck does $|++; do?
by davido (Cardinal) on Apr 13, 2004 at 16:09 UTC
|
$| is the special variable that controls Perl's output buffer flushing. A FALSE value results in normal buffering. A TRUE value sets the buffer to 'autoflush'. Without it, sometimes an output buffer won't get flushed until you've printed a "\n" to it. With it, the buffer gets flushed as soon as there's something in it to flush out.
This is an oversimplification, of course.
Unless you really need to autoflush output buffers, don't worry about this feature.
Of course the ++ just increments the special variable, which gives it a value of 1, which in Perl equates to TRUE.
See perlvar and perlop for further details.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] |
Re: What the heck does $|++; do?
by ViceRaid (Chaplain) on Apr 13, 2004 at 16:10 UTC
|
| [reply] [Watch: Dir/Any] |
Re: What the heck does $|++; do?
by broquaint (Abbot) on Apr 13, 2004 at 16:11 UTC
|
| [reply] [Watch: Dir/Any] |
|
Idiomatic? Needlessly obfuscated, I'd say, without even a gain
in keystrokes. $|=1 takes four keystrokes, $|++ as well, but has more shifted keys. And it gives the false impression that you can turn buffering off by doing
$| -- as often as you've given $| ++.
$| = 0;
$| ++; $| ++; $| --; $| --;
print $|; # prints 1, not 0!
If I were to code review production code, someone writing
$| ++ instead of $| = 1 better have a pretty damn good reason for doing so.
Abigail | [reply] [Watch: Dir/Any] [d/l] |
|
Idiomatic? Needlessly obfuscated, I'd say, I would say both. Part of me dislikes the peculiar ++ behaviour, but in it's defence, it is idiomatic.
Come to think of it, this is another of those cargo cults, isn't it? People doing $|++ without thinking of the consequences, such as non-nestability. If you know that there will not be any nested $| accesses for the same handle, then it's ok.
A minor point, ++ is easier to type than =1 in this case, as you already have your finger on the shift key from the |, so it requires two less actions (release Shift, move finger across keyboard to 1).
| [reply] [Watch: Dir/Any] [d/l] |
|
|
Re: What the heck does $|++; do?
by tachyon (Chancellor) on Apr 13, 2004 at 16:39 UTC
|
| [reply] [Watch: Dir/Any] |
Re: What the heck does $|++; do? .. and why?
by talexb (Chancellor) on Apr 13, 2004 at 17:29 UTC
|
And to respond to 'Why?' .. sometimes a script takes a while to complete, and in some cases you don't care if the output comes out all in the end or in dribs and drabs.
Sometimes (often, in the case of CGI scripts), you are willing to trade off the efficiencies of caching the output until you have a buffer full, with getting the output stream as the script emits it, in real-time.
For a CGI script, you might want to output the HTTP header and the first chunk of the web page while some complicated and lengthy operation happens on the server. This is reassuring to the browser (and the user who is watching the browser) because they can see that *something* is happening. That's unbuffered output ($| == 1).
If a CGI script is buffered ($| == 0, the default), nothing may happen on the browser until the script completes, and this could be frustrating for the user watching the browser.
Alex / talexb / Toronto
Life is short: get busy!
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: What the heck does $|++; do?
by crabbdean (Pilgrim) on Apr 13, 2004 at 19:26 UTC
|
You've already got lots of good comments here but there is a little more to discuss on this topic to fully flesh it out. There are couple ways to flush buffering.
$old_fh = select(OUTPUT_HANDLE);
$| = 1;
select($old_fh);
The 'select' statement above selects OUTPUT_HANDLE as the place to 'print' or 'write' their output and returns the name of the old file_handle that previously was recieving the printed output. You can then set the OUTPUT_HANDLE to be unbuffered and use the returned old handle to later to reset your old file handle as the receiver of output. If you wanted to do the same in a little more bizarre way you could write:
select((select(STDERR), $| = 1)[0])
Alternatively you can use the IO:Handle module:
use IO::Handle;
OUTPUT_HANDLE->autoflush(1);
Or even again alternatively:
use FileHandle;
STDOUT->autoflush(1);
OORRR even again for linguistic nice-ness:
use IO::Handle;
autoflush ONE_HANDLE 1; # unbuffer for clarity
autoflush ANOTHER_HANDLE 0; # buffer this for speed
The above three come with an expense as the 'use'd IO::Handle module require 1000's of lines of code to be read and compiled. It may often be better to use $| directly. But there you go, you have choice!
Additionally I should add that removing buffering does come at an expense ... speed! Computers have buffers for a reason. My rule of thumb is only to turn buffering off if its required, that is, if I'm not seeing my output when I *really* need to. And usually that's when I'm into the testing stage of a script and find I'm not seeing what I should, I then set things unbuffered.
Lastly, Perl's 'print' in an unbuffered state isn't truly unbuffered. Truly unbuffered mean every character one at a time is written. Perl's 'print' is what's called "command buffered". That is, a physical write is made after an ouput command. It means your unbuffered prints aren't as intensive on your system while still getting the results you need.
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: What the heck does $|++; do?
by rinceWind (Monsignor) on Apr 13, 2004 at 16:12 UTC
|
What the heck does $|++; do?
It makes your output pipe piping hot. See perldoc perlvar.
This is useful for interactive programs that prompt on STDOUT, and read from STDIN. Usually you want the user's cursor to stay on the same line as the prompt. But, the default action of print is to wait until it has a complete line (with \n) before writing it out. Setting $| to 1 changes this behaviour.
-- I'm Not Just Another Perl Hacker
| [reply] [Watch: Dir/Any] |
Re: What the heck does $|++; do?
by webfiend (Vicar) on Apr 13, 2004 at 20:21 UTC
|
Mostly it just provides another example of ugly code that gives my Python-using friends a chance to point and gloat. Everybody else has already explained the practical application of setting autoflush. Smack anybody who uses the ++ version, though. That's just not right.
Incidentally, I prefer to avoid this particular messy form and rely on IO::Handle.
use IO::Handle;
my $fh = IO::Handle->new();
if ($fh->fdopen("dump.dat", "w")) {
$fh->autoflush(1);
$fh->print($mystuff);
# ... blah blah blah
$fh->close() or
die("Unable to close file: $!\n");
}
else {
die("Unable to open file: $!\n");
}
... but that's just me. I like the typing exercise if it makes it easier for me to read the code out loud. | [reply] [Watch: Dir/Any] [d/l] [select] |
Re: What the heck does $|++; do?
by Anonymous Monk on Apr 13, 2004 at 18:21 UTC
|
It's pronounced "unclogging the pipe" | [reply] [Watch: Dir/Any] |
Re: What the heck does $|++; do?
by CountZero (Bishop) on Apr 13, 2004 at 20:16 UTC
|
If you really want to switch autoflush on, you can use $|++, but perhaps think of local-izing it so the effects are limited to the block or scope it is in.
CountZero "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: What the heck does $|++; do?
by jaco (Pilgrim) on Apr 13, 2004 at 19:58 UTC
|
while others have touched on this, I'd like to add to it. It seems to me that there is almost no good reason to set autoflush in this manner. More then likely the person who wrote it this way was either c&p from other code, or just learned to do it this way. I's say that unless you have a very special reason for doing so, you should stay away from this format at all costs.
I'm not saying anything that hasn't been mentioned already
| [reply] [Watch: Dir/Any] |
Re: What the heck does $|++; do?
by pizza_milkshake (Monk) on Apr 13, 2004 at 19:57 UTC
|
perldoc perlvar
perl -e'$_="nwdd\x7F^n\x7Flm{{llql0}qs\x14";s/./chr(ord$&^30)/ge;print'
| [reply] [Watch: Dir/Any] [d/l] |