Perl - myprint()或重载打印命令的新定义

时间:2012-04-06 23:47:14

标签: perl printing

我是Perl的新手。我正在编写一些脚本,并希望定义我自己的名为myprint()的打印件,它将根据一些标志打印传递给它的东西(详细/调试标志)

open(FD, "> /tmp/abc.txt") or die "Cannot create abc.txt file";
print FD "---Production Data---\n";
myprint "Hello - This is only a comment - debug data";

有人可以帮我提供myprint()函数的示例代码吗?

2 个答案:

答案 0 :(得分:5)

您是否更关心编写自己的日志记录系统,或者您是否想知道如何将日志语句放在程序的相应部分中,以便关闭它们(并且在关闭时几乎不会造成性能损失)?

如果您想要一个易于开始使用的日志记录系统,但也提供了一个可以逐步发现和使用的功能世界,Log::Log4perl是一个不错的选择。它有一个简单模式,允许您指定所需的日志记录级别,并仅发出超出所需级别的日志消息。

#!/usr/bin/env perl

use strict; use warnings;

use File::Temp qw(tempfile);
use Log::Log4perl qw(:easy);

Log::Log4perl->easy_init({level => $INFO});

my ($fh, $filename) = tempfile;

print $fh "---Production Data---\n";

WARN 'Wrote something somewhere somehow';

该代码段还显示了使用File::Temp打开临时文件的更好方法。

至于覆盖内置print ......除非在非常具体的情况下,否则不要使用内置插件。 perldoc perlsubOverriding Built-in Functions部分。 this question的已接听答案列出了Perl built-ins that cannot be overriddenprint就是其中之一。

但是,真的不需要覆盖内置来编写日志系统。

所以,如果一个已经写好的日志记录系统没有为你做,你似乎真的在问“我如何根据标志的值来编写一个有条件地打印东西的函数?”

这是一种方式:

#!/usr/bin/env perl

package My::Logger;
{
    use strict; use warnings;
    use Sub::Exporter -setup => {
        exports => [
            DEBUG => sub {
                return sub {} unless $ENV{MYDEBUG};
                return sub { print 'DEBUG: ' => @_ };
            },
        ]
    };
}

package main;

use strict; use warnings;

# You'd replace this with use My::Logger qw(DEBUG) if you put My::Logger
# in My/Logger.pm somewhere in your @INC
BEGIN {
    My::Logger->import('DEBUG');
}

sub nicefunc {
    print "Hello World!\n";
    DEBUG("Isn't this a nice function?\n");
    return;
}

nicefunc();

样本用法:

$ ./yy.pl
Hello World!
$ MYDEBUG=1 ./yy.pl
Hello World!
DEBUG: Isn't this a nice function?

答案 1 :(得分:2)

我不打算回答这个问题,因为思南已经有了我推荐的答案,但是今晚我也碰巧正在研究即将到来的Intermediate Perl的“Filehandle References”章节。这是几个相关段落,我将直接复制而不会使它们适合您的问题:

<小时/> IO :: Null和IO :: Interactive

有时我们不希望将输出发送到任何地方,但我们被迫 将它发送到某个地方。在这种情况下,我们可以使用IO :: Null来创建 一个简单地丢弃我们提供的任何东西的文件句柄。它看起来 并且就像文件句柄一样,但什么都不做:

use IO::Null;

my $null_fh = IO::Null->new;

some_printing_thing( $null_fh, @args );

其他时候,我们希望在某些情况下输出,但在其他情况下不需要输出。如果我们是 登录并在我们的终端上运行我们的程序,我们可能想要 看到很多输出。但是,如果我们通过 cron 安排工作,我们 只要它完成这项工作,可能并不关心输出。 IO :: Interactive模块足够聪明,可以区分:

use IO::Interactive;

print { is_interactive } 'Bamboo car frame';

is_interactive子例程返回文件句柄。自从 调用子程序不是一个简单的标量变量,我们环绕 它用大括号告诉Perl它是文件句柄。

现在你知道“什么都不做”的文件句柄,你可以替换一些 每个人都倾向于编写丑陋的代码。在某些情况下,您需要输出 在某些情况下你没有,所以很多人使用后表达式 条件是在某些情况下关闭声明:

print STDOUT "Hey, the radio's not working!" if $Debug;

您可以根据$debug_fh分配不同的值,而不是这样 在你想要的任何条件下,然后留下丑陋的if $Debug 在每个print

的末尾
use IO::Null;

my $debug_fh = $Debug ? *STDOUT : IO::Null->new;

$debug_fh->print( "Hey, the radio's not working!" );

IO :: Null背后的魔力可能会发出关于“print()on”的警告 未打开的文件句柄GLOB“使用间接对象表示法(例如 print $debug_fh)尽管它运作得很好。我们不明白 直接警告。