in reply to How do I redirect STDERR to a subroutine?

Well, for Safe::World I made a full redirection of STDOUT and STDERR, with the option to redirecto to another HANDLER, SUB or SCALAR.

I have striped this code from it:

## Redirecting to another IO: tie(*STDERR => 'Safe::World::stderr' , \*STDOUT ) ; ## Redirecting to a SUB: sub errors { print "ERR>> @_\n" ;} tie(*STDERR => 'Safe::World::stderr' , \&errors ) ; ## Redirecting to a scalar: my $stderr ; tie(*STDERR => 'Safe::World::stderr' , \$stderr ) ; print "REDIRECT << $stderr >>\n" ; package Safe::World::stderr ; sub print_stderr { my $this = shift ; my $stderr = $this->{STDERR} ; if ( ref($stderr) eq 'SCALAR' ) { $$stderr .= $_[0] ;} elsif ( ref($stderr) eq 'CODE' ) { &$stderr($_[0]) ;} else { print $stderr $_[0] ;} return 1 ; } sub TIEHANDLE { my $class = shift ; bless( { STDERR => $_[0] } , $class) ; } sub PRINT { my $this = shift ; $this->print_stderr( join("", (@_[0..$#_])) ) ; return 1 ; } sub PRINTF { &PRINT($_[0],sprintf($_[1],@_[2..$#_])) ;} sub READ {} sub READLINE {} sub GETC {} sub WRITE {} sub FILENO {} sub CLOSE {} sub DESTROY {}
Note that if you want to catch all the error messages, you also should set $SIG{__WARN__} and $SIG{__DIE__}:
$SIG{__WARN__} = \&print_stderr ; $SIG{__DIE__} = \&handle_die ;

Enjoy! ;-P

Graciliano M. P.
"Creativity is the expression of the liberty".

Replies are listed 'Best First'.
Re^2: How do I redirect STDERR to a subroutine?
by Boldra (Deacon) on May 26, 2008 at 09:23 UTC
    That's interesting code; I really liked this bit in the PRINT sub :) @_[0..$#_] A bit of unnecessary redundancy?
Re^2: How do I redirect STDERR to a subroutine?
by mde (Initiate) on Feb 13, 2010 at 22:37 UTC

    Thanks very much for this.

    Filter::Handle didn't work for me when trying to divert stderr to a subroutine (it went into an infinite loop), but your code works perfectly.

    mde, London, England