2
我需要與某些不幸將診斷 消息記錄到STDOUT和STDERR的庫一起工作。通過使用tie
,我可以將這些寫入到一個捕獲這些函數的函數中。由於我不希望所有 我的程序的STDOUT和STDERR輸出通過 捆綁手柄被捕獲,我只想爲某些包執行此操作。如何使用tie()重定向STDOUT,STDERR僅適用於某些包?
我想出了在實際行爲是通過看來電顯示()作爲可以看到下面確定 一個解決方案,但我有一種感覺 認爲必須有一個更好的辦法?有沒有更優雅的方案?
package My::Log::Capture;
use strict;
use warnings;
use 5.010;
sub TIEHANDLE {
my ($class, $channel, $fh, $packages) = @_;
bless {
channel => lc $channel,
fh => $fh,
packages => $packages,
}, $class;
}
sub PRINT {
my $self = shift;
my $caller = (caller)[0];
if ($caller ~~ $self->{packages}) {
local *STDOUT = *STDOUT;
local *STDERR = *STDERR;
given ($self->{channel}) {
when ('stdout') {
*STDOUT = $self->{fh};
}
when ('stderr') {
*STDERR = $self->{fh};
}
}
# Capturing/Logging code goes here...
} else {
$self->{fh}->print(@_);
}
}
1;
package main;
use My::Foo;
# [...]
use My::Log::Capture;
open my $stderr, '>&', *STDERR;
tie *STDERR, 'My::Log::Capture', (stderr => $stderr, [qw<My::Foo>]);
# My::Foo's STDERR output will be captured, everyone else's STDERR
# output will just be relayed.
順便說一句,如果你只需要擔心'STDOUT',你也許可以做到這隻用'select'。 – zostay 2012-07-13 12:14:06
感謝您指點我'選擇'。 – hillu 2012-07-15 12:49:54