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

Hi
I use the Filter::Handle class to redirect
the STDOUT to a file. I use it thus:
use Filter::Handle qw/subs/; . . . Filter \*STDOUT, sub { local $_ = "@_" print <FH1> "$_\n"; $_};
I get the following error message when using a filter:
Deep recursion on subroutine "Filter::Handle::PRINT" at /lib/myfiltermodule.pm line 19 (#1) (W recursion) This subroutine has called itself (directly or indir +ectly) 100 times more than it has returned. This probably indicates an infin +ite recursion, unless you're writing strange benchmark programs, in wh +ich case it indicates something else. Deep recursion on anonymous subroutine at /lib/Filter/Handle.pm line 4 +2.
Any suggestions would be helpful
Thanks

update (broquaint): fixed formatting

Replies are listed 'Best First'.
Re: Filter::Handle - Deep Recursion Error
by BrowserUk (Patriarch) on Jun 04, 2003 at 01:59 UTC

    The problem is that you are using the module in the wrong way for your intended purpose. Using the Filter method is intended to allow you to filter the output on its way to the given file.

    That is to say, it doesn't redirect the output, just gives you the opportunity to modify it on its way through, as is (slightly confusingly) described in the pod:

    =item * Capturing Output

    Normally, output is passed through your filtering function, then printed on the output filehandle that you're filtering.

    Suppose that, instead ofwriting the filtered output to the filehandle, you just want to capture that filtered output. In other words, you want to store the output and not have it written to the filehandle.

    A second problem, and the reason for the deep recursion, is that the syntax:

     print <FH1> "$_\n"; isn't doing what you intend. <FH1> means "read from FH1".

    So the line is attempting to read from FH1, and then print the results to STDOUT, but of course you are filtering STDOUT, so that line causes your filter function to be called, which reads from FH1 and prints the results to STDOUT, which...:)

    To redirect the output from one filehandle to another, you should be using the tie interface...

    #! perl -slw use strict; use Filter::Handle; open FH1, '>', 'my.log' or die $!; tie *STDOUT, 'Filter::Handle', \*FH1, sub{ $_[0] }; print 'Hello world!', $_ for 1 .. 10;

    You can modify the anonymous sub on the tie to also filter the output, or omit the parameter to get the default filtering effect of each line being prefixed by the filename and linenumber.

    If you are not intending to use the filtering facilities of Filter::Handle, and are only using it to re-direct the output from STDOUT to FH1, then adding

    BEGIN{ open FH1, '>', 'my.log' or die $!; *STDOUT = *FH1; }
    to the top of your program would be much simpler and more efficient.
    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


      Hi Thank you very much for replying back. I made the changess thus: tie *FH1, 'Filter::Handle', \*FH2, sub { $_[0] }; . . print FH1 "Hello World\n"; But I donot see the Hello World in FH2. That means my Filter is not working correctly. It would be of great help if you could let me know. Thanks

        The following works for me?

        Update: Note: I had to change the anonymous sub slightly to use @_ instead of $_[0]. Only the first argument to the print statement was being output.

        #! perl -slw use strict; use Filter::Handle; open FH1, '>', 'my.log' or die $!; open FH2, '>', 'myother.log' or die $!; tie *FH1, 'Filter::Handle', \*FH2, sub{ @_ }; ## << NOTE THE CHANGE!!! print FH1 'Hello world!', $_ for 1 .. 10;

        The test

        That said, I'm not quite sure why you would do this? If all the print statements you wish to re-direct already print to an filehandle, why not just open the desired output file as that handle?


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


Re: Filter::Handle - Deep Recursion Error
by chromatic (Archbishop) on Jun 04, 2003 at 01:17 UTC

    I think the indirect object notation is tripping you up. Plus, you're reading a line from FH1, not printing to it. Your problem might be solved with:

    print FH1 "$_\n";

    but I'd be more comfortable with:

    FH1->print( "$_\n" );