这是一个场景.您有大量遗留脚本,都使用公共库.所述脚本使用'print'语句进行诊断输出.脚本不允许任何变化 - 它们的范围广泛,得到了批准,并且早已离开了监督和控制的富有成效的山谷.
现在出现了新的需求:现在必须将日志记录添加到库中.这必须自动且透明地完成,标准库的用户无需更改其脚本.公共库方法可以简单地添加日志记录调用; 这是最简单的部分.困难的部分在于这些脚本的诊断输出始终使用'print'语句显示.必须存储此诊断输出,但同样重要的是,处理.
作为此处理的示例,库应仅记录包含"警告","错误","通知"或"注意"字样的打印行.下面的极其琐碎和被控制的示例代码(tm)将记录一些所述输出:
sub CheckPrintOutput
{
my @output = @_; # args passed to print eventually find their way here.
foreach my $value (@output) {
Log->log($value) if $value =~ /warning|error|notice|attention/i;
}
}
Run Code Online (Sandbox Code Playgroud)
(我想避免诸如"实际上应该记录什么","打印不应该用于诊断","perl糟透了"或"此示例有缺陷xy和z'等问题......这是为简洁和清晰而大大简化.)
基本问题归结为捕获和处理传递给print的数据(或任何perl builtin,沿着这些推理线).可能吗?有什么方法干净利落的吗?是否有任何具有钩子的记录模块可以让你这样做?或者它应该像瘟疫一样应该避免,我应该放弃捕获和处理打印输出?
附加:这必须运行跨平台 - 窗口和*nix相似.运行脚本的过程必须保持不变,脚本的输出也必须保持不变.
其他附加:在codelogic的回答评论中提出了一个有趣的建议:
您可以继承http://perldoc.perl.org/IO/Handle.html并创建自己的文件句柄来执行日志记录工作. - Kamil Kisiel
这可能会这样做,有两点需要注意:
1)我需要一种方法将此功能导出到使用公共库的任何人.它必须自动应用于STDOUT,也可能是STDERR.
2) IO :: Handle文档说你不能将它子类化,到目前为止我的尝试都没有结果.是否有任何特殊需要使子类化IO :: Handle工作?标准的'使用基础'IO :: Handle'然后覆盖new/print方法似乎什么都不做.
最终编辑:看起来像IO :: Handle是一个死胡同,但Tie :: Handle可能会这样做.感谢所有的建议; 他们都非常好.我将试试Tie :: Handle路线.如果它导致问题我会回来的!
附录:请注意,在使用了这个之后,我发现如果你没有做任何棘手的事情,Tie :: Handle会起作用.如果您使用IO :: Handle的任何功能与绑定的STDOUT或STDERR,它基本上是一个让它们可靠地工作的废话 - 我找不到一种方法来获得IO :: Handle的autoflush方法来处理我的绑定处理.如果我在绑上手柄之前启用了autoflush,它就能正常工作.如果这对您有用,可以接受Tie :: Handle路线.
我正在寻找一个使用Perl将stdout重定向到文件的示例.我正在做一个相当简单的fork/exec工具,我想将子输出重定向到文件而不是父项stdout.
有没有dup2()我应该使用的等效物?我似乎找不到它
我想用ROUGE分析我的摘要.到目前为止,我已经编写了一个perl脚本来在命令行上运行ROUGE,这是我到目前为止所做的:
#!/usr/bin/perl
use warnings;
use Cwd;
$curdir=getcwd;
$ROUGE="/ROUGE-1.5.5.pl";
chdir("sample-test");
$cmd="$ROUGE -e /data -c 95 -2 -1 -U -r 1000 -n 4 -w 1.2 -a DUC2002ROUGE.in.26.spl.xm> /sample-output/salam.out";
print $cmd,"\n";
system($cmd);
chdir($curdir);
Run Code Online (Sandbox Code Playgroud)
但是我收到此错误:
系统找不到指定的路径