当前位置:  开发笔记 > 编程语言 > 正文

我如何勾选Perl的印刷品?

如何解决《我如何勾选Perl的印刷品?》经验,为你挑选了3个好方法。

这是一个场景.您有大量遗留脚本,都使用公共库.所述脚本使用'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;
    }
}

(我想避免诸如"实际上应该记录什么","打印不应该用于诊断","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路线.



1> Axeman..:

您可以覆盖许多内置函数(请参阅perlsub).但是,print其中一个内置函数不能以这种方式工作.print这个perlmonk的主题详细说明了覆盖的困难.

但是,你可以

    创建一个包

    系好手柄

    选择此句柄.

现在,有几个人已经给出了基本框架,但它有点像这样:

package IO::Override;
use base qw;
use Symbol qw;

sub TIEHANDLE { return bless geniosym, __PACKAGE__ }

sub PRINT { 
    shift;
    # You can do pretty much anything you want here. 
    # And it's printing to what was STDOUT at the start.
    # 
    print $OLD_STDOUT join( '', 'NOTICE: ', @_ );
}

tie *PRINTOUT, 'IO::Override';
our $OLD_STDOUT = select( *PRINTOUT );

您可以printf以相同的方式覆盖:

sub PRINTF { 
    shift;
    # You can do pretty much anything you want here. 
    # And it's printing to what was STDOUT at the start.
    # 
    my $format = shift;
    print $OLD_STDOUT join( '', 'NOTICE: ', sprintf( $format, @_ ));
}

请参阅Tie :: Handle,了解STDOUT的所有行为.



2> codelogic..:

您可以使用Perl的select来重定向STDOUT.

open my $fh, ">log.txt";
print "test1\n";
my $current_fh = select $fh;
print "test2\n";
select $current_fh;
print "test3\n";

文件句柄可以是任何东西,甚至是管道处理日志消息的另一个进程的管道.

PerlIO :: Util模块中的PerlIO :: tee似乎允许您将文件句柄的输出"发送"到多个目的地(例如,日志处理器和STDOUT).



3> ysth..:

很多选择.使用select()更改打印默认的文件句柄.或者打STDOUT.或者重新打开它.或者为其应用IO层.

推荐阅读
mobiledu2402852357
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有