Re: How do I redirect STDERR to a subroutine?
by stvn (Monsignor) on Feb 17, 2004 at 21:49 UTC
|
If you really want to redirect *STDERR, then tieing is probably the way to go. But it seems to me (from what i can gather from your very short post) that maybe you really just want to catch all warnings that are generated by perl and act upon their contents. Maybe I am wrong, but if not then I think you might actually be looking for $SIG{__WARN__} instead. See the warn perl doc page for more info.
- stvn
| [reply] [Watch: Dir/Any] [d/l] |
Re: How do I redirect STDERR to a subroutine?
by BUU (Prior) on Feb 17, 2004 at 21:30 UTC
|
tie *STDERR,'MyRandomPackageName';
package MyRandomPackageName;
sub TIEHANDLE { bless {}; }
sub PRINT { CORE::print(@_); }
sub PRINTF{ CORE::print(sprintf@_); }
#etc
| [reply] [Watch: Dir/Any] [d/l] |
|
| [reply] [Watch: Dir/Any] |
Re: How do I redirect STDERR to a subroutine?
by gmpassos (Priest) on Feb 18, 2004 at 05:00 UTC
|
## 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".
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
That's interesting code; I really liked this bit in the PRINT sub :)
@_[0..$#_]
A bit of unnecessary redundancy?
| [reply] [Watch: Dir/Any] [d/l] |
|
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
| [reply] [Watch: Dir/Any] |
Re: How do I redirect STDERR to a subroutine?
by RhetTbull (Curate) on Feb 18, 2004 at 01:55 UTC
|
I usually use Filter::Handle for this sort of thing. There's a code snippet that shows how to do this here. | [reply] [Watch: Dir/Any] |
Re: How do I redirect STDERR to a subroutine?
by samtregar (Abbot) on Feb 17, 2004 at 22:33 UTC
|
Why do you want to do this? I suspect there may be an easier way to meet your needs. Messing with the standard streams should be your last resort.
-sam
| [reply] [Watch: Dir/Any] |
|
You can use the open in conjuction with STDOUT and STDERR redirections, or test the @_ resulting from the eval function ...
Brett
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
|
TMTOWTDI
... and ...
Good advice is not always cross-platform.
:)
| [reply] [Watch: Dir/Any] |
|
I don't know much about Win32, but it sounds like STDERR is broken there. On Linux STDERR is virtually never broken unless you break it yourself. And if you do, there'll be hell to pay. Not too long ago I helped a co-worker track down a very difficult bug; in the end it turned out that he'd effectively closed STDERR and wasn't seeing the simple error message that would have helped him find the problem.
-sam
| [reply] [Watch: Dir/Any] |
|
Re: How do I redirect STDERR to a subroutine?
by Anonymous Monk on Feb 17, 2004 at 22:09 UTC
|
perldoc perltie
perldoc IO::Handle
| [reply] [Watch: Dir/Any] |