0

UPDATE: Changed reading from "DATA" to get data from a sub.

I have to write a protocol to a printer. The printer needs a string to print, so I use perls format processor.

This works fine, for the first time. But if I try to write the protocol twice, the printed data are not correct formatted.

An example of the code I tried in short:

#!/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";
}

The output I get is:

-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

So how can I reset the protocol handle / the protocol processor so that the data is printed correct.

-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

In real the printer is not "STDOUT", of course.

Andy A.
  • 1,392
  • 5
  • 15
  • 28
  • 1
    By seeing your code, you were trying to read `__DATA__` twice. See [this](https://stackoverflow.com/questions/4459601/how-can-i-use-data-twice) if it helps you to read `__DATA__` twice. – vkk05 May 25 '21 at 10:13
  • @vkk05 Ah, thats why there are no data... I will edit my example. – Andy A. May 25 '21 at 10:16
  • As a digression, are there any significant advantages of `format` over `sprintf()`? – mpapec May 25 '21 at 11:11
  • @mpapec Yes, if the protocol need more than one page, some lines are formatted more complex... This is a basic example, but it shows my problem. In real my head has 16 lines of code and each entry 11 ones. – Andy A. May 25 '21 at 11:23
  • You might want to consider using Perl6::Form (a module for Perl5) instead of formats – ikegami May 25 '21 at 22:10
  • @ikegami I'll keep in mind! But I work with a ERP-software where perl is integrated. I can't change versions or add new modules so. Thats why I look about standard perl most times. – Andy A. May 26 '21 at 05:33
  • That's complete nonsense. If you can add your program, you can add a module. And I specifically said you don't need to change version. – ikegami May 26 '21 at 05:46
  • @ikegami It might be nonsense, but I'm perl programmer since march this year. I'm new in my job, I only extend already existing programs and these programs should run on livesystems where it is not easy loading new modules on it. Its not a good idea to me to turn the complete code inside out. (It's overact, I know...) – Andy A. May 26 '21 at 05:56

1 Answers1

1

I could able to replicate the issue which you have mentioned in the question.

Just declare $h_protocol FH inside the print_protocol() sub. And remove it from line 12.

So your code in sub would look like this.

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

Now the script could able to generate expected result.

Output:

-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
vkk05
  • 3,137
  • 11
  • 25
  • Yes this works fine so far. I need to check how I can get global access to `$h_protocol`. In real there is an "initialize" (`open`, `select(...)` ), a "set_entry" (`write`) and a "print" (`close`) sub. – Andy A. May 25 '21 at 11:35
  • Works well if I use 2 variables: A global one `$h_protocol` and in the initialize sub: `... open my $h_temp, ...` and then `$h_protocol = $h_temp;`. – Andy A. May 25 '21 at 11:56
  • @AndyA. Okay. But why you need `$h_protocol` as a global variable? – vkk05 May 25 '21 at 12:04
  • 1
    Because its easy to write to the protocol from everywhere. The three function I told about needs the handle. And to set it as argument, just makes the code looks big, I think. – Andy A. May 25 '21 at 12:08