Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl Print buffering flush

I have the following Perl code:

STDOUT->autoflush(1);

foreach(...)
{
    ...

    foreach(...)
    {
        print("Processing $folder");
        $|=1;
        process($folder);
    }
    ...
}

but the print statement works only in the first iteration of the loop and does not print anything after that. Any idea why?

EDIT: I found the reason and have added it in the answer also. The solution was:

I added the following line inside the loop and it worked:

select STDOUT;

I think the code in process() function should have been modifying the default output buffer. It was a code written by somebody else!

I am not sure if this is a problem with Perl which allows this or the developer who did not change it back to the default.

The final code looked like this:

foreach(...)
{
    ...

    foreach(...)
    {
        select STDOUT;

        print("Processing $folder");
        $|=1;
        process($folder);
    }
    ...
}

Thanks all...

like image 338
Manoj Avatar asked Aug 03 '09 11:08

Manoj


People also ask

How do I flush a file in Perl?

If you just want to flush the Perl buffer, you can close the file, print a string containing "\n" (since it appears that Perl flushes on newlines), or use IO::Handle 's flush method. You can also, per the perl faq use binmode or play with $| to make the file handle unbuffered.

What does Autoflush do in Perl?

examples/autoflush.pl By default a filehandle is buffered. In this example we use the autoflush method of the filehandle object to make it flush to the file automatically.

What is $| in Perl?

$| is the built-in variable for autoflush.


2 Answers

Good detective work in tracking down this problem!

I'd like to suggest an alternate solution.

Rather than having select() wars with the author of process(), you could use the IO::Handle interface to STDOUT:

use IO::Handle;

foreach(...)
{
    ...

    foreach(...)
    {
        STDOUT->printflush("Processing $folder");

        process($folder);
    }
    ...
}
like image 138
daotoad Avatar answered Oct 25 '22 19:10

daotoad


I added the following line inside the loop and it worked:

select STDOUT;

I think the code in process() function should have been modifying the default output buffer. It was a code written by somebody else!

I am not sure if this is a problem with Perl which allows this or the developer who did not change it back to the default.

The final code looked like this:

foreach(...)
{
    ...

    foreach(...)
    {
        select STDOUT;

        print("Processing $folder");
        $|=1;
        process($folder);
    }
    ...
}

Thanks all...

like image 27
Manoj Avatar answered Oct 25 '22 18:10

Manoj