【问题标题】:How to reinitialize perls format processor如何重新初始化 perls 格式处理器
【发布时间】:2021-05-25 09:39:18
【问题描述】:

更新:将读取从“DATA”更改为从子获取数据。

我必须将协议写入打印机。打印机需要一个字符串来打印,所以我使用 perls 格式处理器。

这是第一次正常工作。但是如果我尝试两次编写协议, 打印的数据格式不正确。

简而言之我尝试的代码示例:

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use utf8;

my $a;
my $b;
my $c;
my $protocol;
my $h_protocol;

format F_TOP =
---------------------------
1     2       3        P: @
                         $%
---------------------------
.

format F_ENTRY =
@<<<  @<<<    @<<<
$a,   $b,     $c
.

print_protocol("-1-");  # First run
print_protocol("-2-");  # Second run - should gibe the same output

sub print_protocol {    
    my $run = shift;
    print "$run\n";
    
    # Open protocol string as filehandle
    open $h_protocol, ">", \$protocol;
    # Set format to protocol filehandle
    select((select($h_protocol),        # Filehandle
            $~ = "F_ENTRY",
            $^ = "F_TOP",
            $= = 5                      # Lines per page
           )[0]);
           
    # Write data in protocol "file"
    my @data = split /\n/, get_data();
    for (@data) {
        ($a, $b, $c) = split /;/;
        write $h_protocol;
    }
    
    # close filehandle
    close $h_protocol;
    
    # Print the protocol (to STDOUT to test)
    print $protocol;
    # Delete protocol data
    $protocol = "";
}

sub get_data {
    return "abc;def;ghi\njkl;mno;pqr\nabc;def;ghi\njkl;mno;pqr\nqwe;eqw;weq";
}

我得到的输出是:

-1-
---------------------------
1     2       3        P: 1
---------------------------
abc   def     ghi
jkl   mno     pqr
♀---------------------------
1     2       3        P: 2
---------------------------
abc   def     ghi
jkl   mno     pqr
♀---------------------------
1     2       3        P: 3
---------------------------
qwe   eqw     weq
-2-
abc   def     ghi
jkl   mno     pqr
abc   def     ghi
jkl   mno     pqr
qwe   eqw     weq

那么我该如何重置协议句柄/协议处理器,以便正确打印数据。

-1-
---------------------------
1     2       3        P: 1
---------------------------
abc   def     ghi
jkl   mno     pqr
♀---------------------------
1     2       3        P: 2
---------------------------
abc   def     ghi
jkl   mno     pqr
♀---------------------------
1     2       3        P: 3
---------------------------
qwe   eqw     weq
-2-
---------------------------
1     2       3        P: 1
---------------------------
abc   def     ghi
jkl   mno     pqr
♀---------------------------
1     2       3        P: 2
---------------------------
abc   def     ghi
jkl   mno     pqr
♀---------------------------
1     2       3        P: 3
---------------------------
qwe   eqw     weq

当然,实际上打印机不是“STDOUT”。

【问题讨论】:

  • 通过查看您的代码,您试图阅读__DATA__ 两次。如果对您阅读__DATA__ 两次有帮助,请参阅this
  • @vkk05 啊,这就是为什么没有数据...我将编辑我的示例。
  • 题外话,formatsprintf() 有什么显着优势吗?
  • @mpapec 是的,如果协议需要超过一页,则某些行的格式会更复杂......这是一个基本示例,但它显示了我的问题。实际上,我的脑袋有 16 行代码,每个条目 11 行。
  • 您可能需要考虑使用 Perl6::Form(Perl5 的一个模块)而不是格式

标签: perl format


【解决方案1】:

我可以复制您在问题中提到的问题。

只需在print_protocol() sub 中声明$h_protocol FH。并将其从第 12 行删除。

所以你在 sub 中的代码看起来像这样。

sub print_protocol {    
    my $run = shift;
    print "$run\n";
    
    # Open protocol string as filehandle
    open my $h_protocol, ">", \$protocol;
    # Set format to protocol filehandle
    ...
    ...
}

现在脚本可以生成预期的结果了。

输出:

-1-
---------------------------
1     2       3        P: 1
---------------------------
abc   def     ghi
jkl   mno     pqr

---------------------------
1     2       3        P: 2
---------------------------
abc   def     ghi
jkl   mno     pqr

---------------------------
1     2       3        P: 3
---------------------------
qwe   eqw     weq
-2-
---------------------------
1     2       3        P: 1
---------------------------
abc   def     ghi
jkl   mno     pqr

---------------------------
1     2       3        P: 2
---------------------------
abc   def     ghi
jkl   mno     pqr

---------------------------
1     2       3        P: 3
---------------------------
qwe   eqw     weq

【讨论】:

  • 是的,到目前为止效果很好。我需要检查如何获得对$h_protocol 的全局访问权限。实际上有一个“初始化”(openselect(...)),一个“set_entry”(write)和一个“打印”(close)子。
  • 如果我使用 2 个变量效果很好:一个全局变量 $h_protocol 并在初始化子中:... open my $h_temp, ... 然后 $h_protocol = $h_temp;
  • @AndyA。好的。但是为什么需要$h_protocol 作为全局变量呢?
  • 因为它很容易从任何地方写入协议。我讲的三个函数都需要句柄。并将其设置为参数,我认为只会让代码看起来很大。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
  • 2020-08-17
  • 2023-01-16
  • 2013-08-11
  • 2016-06-26
  • 2012-08-24
相关资源
最近更新 更多