我需要使用一些不幸记录诊断的库
发送至 STDOUT 和 STDERR 的消息。通过使用tie
,我可以重定向那些
写入捕获这些的函数。既然我不想要全部
我的程序的 STDOUT 和 STDERR 输出通过
捆绑手柄,我只想对某些包裹执行此操作。
我提出了一个确定实际行为的解决方案
通过查看 caller() 如下所示,但我有这种感觉
必须有更好的方法...有更优雅的解决方案吗?
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
and STDERR
文件句柄转换为您自己的文件句柄。然后,重新打开STDOUT
and STDERR
和你绑着的把手。
例如,您可以这样做STDOUT
:
open my $fh, ">&", \*STDOUT or die "cannot reopen STDOUT: $!";
close STDOUT;
open STDOUT, ">", "/tmp/test.txt";
say $fh "foo"; # goes to real STDOUT
say "bar"; # goes to /tmp/test.txt
你可以阅读perldoc -f 打开 http://perldoc.perl.org/functions/open.html有关“>&”之类的所有详细信息。
无论如何,您可以用绑定文件句柄的设置替换该打开调用,而不是“/tmp/test.txt”。
您的代码必须始终使用显式文件句柄来写入或使用select http://perldoc.perl.org/functions/select.html切换文件句柄:
select $fh;
say "foo"; # goes to real STDOUT
select STDOUT;
say "bar"; # goes to /tmp/test.txt
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)