Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

What the heck does $|++; do?

by Anonymous Monk
on Apr 13, 2004 at 16:04 UTC ( [id://344772]=perlquestion: print w/replies, xml ) Need Help??

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

Oh wise Monks,
I see $|++; in many Perl scripts.
  • What does it do?
  • Why would you want to do that?
  • Does $|++; have a name or how do you say it?
  • Replies are listed 'Best First'.
    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.


      Dave

        Of course the ++ just increments the special variable, which gives it a value of 1,
        It doesn't just increment it - these special variables have magical behaviour, as Abigail-II points out below.

        Oh, and I'd pronounce it "Scalar pipe plus plus" or "Scalar pipe increment". I might say "Dollar" instead of "Scalar" if I was talking to a Perl newbie.

    Re: What the heck does $|++; do?
    by ViceRaid (Chaplain) on Apr 13, 2004 at 16:10 UTC
    Re: What the heck does $|++; do?
    by broquaint (Abbot) on Apr 13, 2004 at 16:11 UTC
      It's an idiomatic way of turning off output buffering, as controlled by the $| variable. See. perlvar and Perl Idioms Explained - $|++ for more info.
      HTH

      _________
      broquaint

      update: s/on/off/, thanks to halley for spotting that

        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

          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).

    Re: What the heck does $|++; do?
    by tachyon (Chancellor) on Apr 13, 2004 at 16:39 UTC
    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!

    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.

      Dean
      The Funkster of Mirth
      Programming these days takes more than a lone avenger with a compiler. - sam
      RFC1149: A Standard for the Transmission of IP Datagrams on Avian Carriers
    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

    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.

    Re: What the heck does $|++; do?
    by Anonymous Monk on Apr 13, 2004 at 18:21 UTC
      It's pronounced "unclogging the pipe"
    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

    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
    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'

    Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Domain Nodelet?
    Node Status?
    node history
    Node Type: perlquestion [id://344772]
    Approved by Sprad
    Front-paged by thelenm
    help
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this?Last hourOther CB clients
    Other Users?
    Others learning in the Monastery: (6)
    As of 2024-03-19 08:02 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      No recent polls found