避免在eval中重新定义perl格式

时间:2013-10-24 19:19:22

标签: perl

我有一个子程序可以在eval表达式中对format进行说明。如果多次调用此子例程,perl会警告已重新定义格式。

此代码:

use warnings;
routine();
routine();

sub routine{
    my $s = "FAIL";
    my $def = "format =\n@<<<<@>>>>\n\$s, \$s\n.";
    eval $def;
    write;
}

打印

FAIL  FAIL
Format STDOUT redefined at (eval 2) line 1.
FAIL  FAIL

是否可以删除子程序末尾的格式声明?

1 个答案:

答案 0 :(得分:1)

这是一个简单的解决方案,它使用标志来避免重新定义格式。

use strict;
use warnings;

routine();
routine();

my $format_defined;

sub routine{
    my $s = "FAIL";
    if (!$format_defined) {
        my $def = "format =\n@<<<<@>>>>\n\$s, \$s\n.";
        eval $def;
        $format_defined = 1;
    }
    write;
}

这是一个更复杂的解决方案,允许为每个调用重新定义格式。它使用临时文件句柄代替STDOUT,将输出重定向到标量,然后您可以将其打印到STDOUT。

routine('FAIL');
routine('PASS');

sub routine{
    my $s = shift;

    format REPORT =
@<<<<@>>>>
$s,  $s
.
    my $report;
    open my $fh, '>', \$report;
    select $fh;
    $~ = 'REPORT';
    write;
    close $fh;

    select STDOUT;
    print $report;
}