in reply to Filter::Handle - Deep Recursion Error

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


Replies are listed 'Best First'.
Re: Re: Filter::Handle - Deep Recursion Error
by bayruds (Acolyte) on Jun 04, 2003 at 03:00 UTC
    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


        I actually work with bayruds, and we were sharing this code snippet, but I'm having a slightly different problem with this. The deep recursion is only showing up in Perl-5.8.0. Previous versions do not have this problem.

        Secondly, we're using the Filter::Handle module to split STDERR to both a logfile and to the terminal. For this I have been using (until switching to Perl-5.8.0) the following code snippet:

        use Filter::Handle qw/subs/; ## $LOG_FH is a FileHandle reference... Filter \*STDERR, sub { local $_ = @_; if (defined $LOG_FH) {print $LOG_FH "STDERR: $_";} $_ }; ## Need a signal handler to capture warnings from carp ## and warn which are not captured by Filter::Handle ## (but by capturing ourselves and printing to STDERR, ## they do get picked up by Filter::Handle)... $SIG{__WARN__} = sub { local $_ = "@_"; print STDERR $_; };
        I don't want to just tie STDERR to the $LOG_FH filehandle, I want to print to both STDERR and the filehandle.

        Beginning with Perl-5.8.0, any output to STDERR, either explicitly or from Perl (e.g. uninitialized variable) results in a deep recursion error. Any thoughts about this?? Why is this happening only in Perl-5.8.0?
        thanks,
        -Cadphile