ppm has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

i've problems with format an perl. so for e.g. i have a format in format.pl like this:

format HEADER = Menge Art.nr. Bezeichnung Preis(€) Gesamt(€) _____________________________________________________________________ . format INHALT = @<<<< ^<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>> @>>>>>>>>> $menge,$nr,$text,$preis,$summe, ~~ ^<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<< $nr, $text . format FOOTER = _____________________________________________________________________ Warenwert: @>>>>>>>>> $gesamt .
In my mainscript i have include this and do the output like this:
$~ = "HEADER"; write; $~ = "INHALT"; foreach (0..$#bestellung) { ($text, $nr, $preis, $menge) = split(/\|/, $bestellung[$_]); $summe = sprintf("%.2f", $menge*$preis); ... irgendwas ... write; } $~ = "FOOTER"; write;
So, what i want is to route the whole write() into a string (e.g. $output). i've found in perldoc a section to do this with the accumolator var ($^A) but i've now idea how to do this for my e.g.

Any ideas .. thx for you help!

ppm

Replies are listed 'Best First'.
Re: How to route a format into a variable
by jmcnamara (Monsignor) on Feb 12, 2003 at 18:45 UTC

    Here is a short example using formline and the accumulator based on your code. I simplified the INHALT format because I wasn't fully sure what you wanted to do with the ~~:
    #!/usr/bin/perl -w use strict; # Store the formats in variables my $header = << 'HEADER'; Menge Art.nr. Bezeichnung Preis(?) Gesamt(?) __________________________________________________________________ +___ HEADER my $body = << 'INHALT'; @<<<< ^<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>> @>>>>>>>>> INHALT my $footer = << 'FOOTER'; __________________________________________________________________ +___ Warenwert: @>>>>>>>>> FOOTER # Sample data my @bestellung = ('Text one|1|3.99|7', 'Text two|2|5.49|8', 'Text three|3|7.89|9'); formline($header); foreach (@bestellung) { my ($text, $nr, $preis, $menge) = split /\|/; my $summe = sprintf("%.2f", $menge*$preis); formline($body, $menge,$nr,$text,$preis,$summe); } formline($footer, 1234); print $^A; # Print the accumulator $^A = ''; # Clear the accumulator __END__ prints: Menge Art.nr. Bezeichnung Preis(?) Gesamt(?) __________________________________________________________________ +___ 7 1 Text one 3.99 27.93 8 2 Text two 5.49 43.92 9 3 Text three 7.89 71.01 __________________________________________________________________ +___ Warenwert: 1234

    See also Re: Formats and Variable Scope and Re: format and IO::String.

    --
    John.

      Hey John,

      thx a lot .. this was exactly what i tried to do .. know i've understand the usage of accumulator ;o) best regardes ppm

      Hello again,

      the formline works now fine .. but i've a new problem.

      >> I wasn't fully sure what you wanted to do with the ~~:

      I will format the Information at "Art.nr." and "Bezeichnung" for multiline output ... In the normal format i will do this with ~~ :

      format INHALT = @<<<< ^<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>> @>>>>>>>>> $menge,$nr,$text,$preis,$summe, ~~ ^<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<< $nr, $text .
      But this doesn't work with the formline example .. there are any solutions?

      thx again! ppm

Re: How to route a format into a variable
by pfaut (Priest) on Feb 12, 2003 at 17:30 UTC

    There are some modules like IO::Stringy that allow doing I/O on variables. You should be able to get what you want using one of those modules.

    Update: Don't go there. There's no cheese down that corridor.

    --- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';
      write does not work with tied handles, probably because a format is different from a file handle (though both are stored in and accessed through globs), and those modules create tied file handles, not "format handles".

      You would use formline and $^A as in Kanji's example below, or see what I once did for a more complicated example.

Re: How to route a format into a variable
by jmcnamara (Monsignor) on Feb 13, 2003 at 23:52 UTC

    Here is take two based on your comments.

    With formline the double tilda ~~ is applied to the entire format "picture" so it doesn't do what you want it to do.

    Instead you have to repeat the formline() while there is still data to write. I've modified the example to show one way of doing it:

    #!/usr/bin/perl -w use strict; # Store the formats in variables (you don't have to use here-docs) my $header = << 'HEADER'; Menge Art.nr. Bezeichnung Preis($) Gesamt +($) __________________________________________________________________ +___ HEADER my $body = << 'INHALT'; @<<<< ^<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>> @>>>>>>>>> INHALT my $continue = << 'INHALT2'; ^<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<< INHALT2 my $footer = << 'FOOTER'; __________________________________________________________________ +___ Warenwert: @>>>>>>>>> FOOTER # Sample data my @bestellung = ('Long ID number|123456789012345|3.99|7', 'Text two, this is a long line|2|5.49|8', 'Text three, this is the longest line|3|7.89|9') +; formline($header); foreach (@bestellung) { my ($text, $nr, $preis, $menge) = split /\|/; my $summe = sprintf("%.2f", $menge*$preis); formline($body, $menge,$nr,$text,$preis,$summe); while (length $nr or length $text) { formline($continue, $nr,$text); } } formline($footer, 1234); print $^A; # Print the accumulator $^A = ''; # Clear the accumulator __END__ Prints: Menge Art.nr. Bezeichnung Preis($) Gesamt +($) __________________________________________________________________ +___ 7 123456789 Long ID number 3.99 27.93 012345 8 2 Text two, this is a long 5.49 43.92 line 9 3 Text three, this is the 7.89 71.01 longest line __________________________________________________________________ +___ Warenwert: 1234

    --
    John.

Re: How to route a format into a variable
by physi (Friar) on Feb 12, 2003 at 17:43 UTC
    Just a question,
    if you want your formated output alltogether in on variable, why don't you use  sprintf and concat all the lines together in one string, or maybe one array ?

    -----------------------------------
    --the good, the bad and the physi--
    -----------------------------------
    
      >> why don't you use sprintf

      i don't know how to do this with formats ;o) do you have a solution?

        There is an example of a sprintf-like function emulating write in the Perl Formats documentation, reproduced below for convenience.

        use Carp; sub swrite { croak "usage: swrite PICTURE ARGS" unless @_; my $format = shift; $^A = ""; formline($format,@_); return $^A; } $string = swrite(<<'END', 1, 2, 3); Check me out @<<< @||| @>>> END print $string;

            --k.