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



我有一个子例程,它在一个eval表达式中处理一种格式。如果这个子例程被调用多次,perl 会警告格式已被重新定义。

此代码:

use warnings;
routine();
routine();
sub routine{
    my $s = "FAIL";
    my $def = "format =n@<<<<@>>>>n$s, $sn.";
    eval $def;
    write;
}

指纹

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

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

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

use strict;
use warnings;
routine();
routine();
my $format_defined;
sub routine{
    my $s = "FAIL";
    if (!$format_defined) {
        my $def = "format =n@<<<<@>>>>n$s, $sn.";
        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;
}

十年后,我遇到了同样的问题,并意识到让格式足够灵活地工作并不容易。@stevenl提到的解决方案不是那么有效,因为将 eval 限制为仅第一次出现,结果重复格式与第一次评估变量。所以我有很好的表格,与第一条记录的数据相同。第二种解决方案不实现 eval,因此无法动态构建格式定义。

我应用的解决方法只是:

no warnings qw/redefine/;

在子例程的主体内部.
是的,我知道,丑陋但有效。仍在寻找更好的解决方案:)

最新更新