2

我有一个子程序可以在表达式中定义格式。eval如果此子例程被多次调用,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

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

4

1 回答 1

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;
}
于 2013-10-25T09:47:51.000 回答