I/O

format#

Declare a picture-based report template for use by write.

format is a declaration, not an executable statement. It binds a named picture — a block of fixed-column output lines with embedded field markers — to the symbol table, where write later looks it up by name. Pictures do not interpolate variables; each picture line is followed by an argument line whose expressions fill the fields in order. format is a legacy feature of Perl; upstream notes its use is limited and points at perlform for the full field grammar.

Synopsis#

format NAME =
FORMLIST
.

format =          # declares the "STDOUT" format
FORMLIST
.

A FORMLIST is a sequence of lines, each one of three kinds: a comment (# in column 1), a picture line, or an argument line supplying values for the picture line immediately above it. A single . in column 1 terminates the declaration.

What you get back#

format is a declaration and has no runtime value. It installs the compiled picture into the current package’s format table under NAME (or STDOUT if NAME is omitted). It is not called; it is triggered indirectly by write.

The pieces of a picture#

Each picture line mixes literal text with field markers. A field begins with @ (regular field) or ^ (special field, used for fill mode and for blankable numeric fields) and extends through pad characters that set both the width and the justification:

  • < — left-justified text

  • > — right-justified text

  • | — centered text

  • # — right-justified numeric; a leading 0 pads with zeroes; . places the decimal point

  • ... — at the tail of a text field, renders three dots when the value was truncated

  • @* — variable-width field that emits a multi-line scalar verbatim

  • ^* — variable-width field that emits the next line of a scalar and consumes that portion of the source variable

Two suppression tokens may appear anywhere on a picture line and are not part of any field:

  • ~ — if every field on this line is empty, the line is suppressed entirely; the ~ itself renders as a space otherwise

  • ~~ — like ~, and additionally repeats the line until every field on it is exhausted (every source scalar is empty or every shift-style expression returns undef)

perlform.pod gives the full grammar of picture lines including fill mode, multi-line fields, overflow (####), and locale-dependent decimal points.

The argument line#

The line immediately below a picture line is the argument line: a comma-separated list of expressions, one per field, evaluated in list context before the picture is rendered. A single list-returning expression may fill multiple fields. The argument list may be broken across lines if and only if the first token on the first line is an opening brace:

format Report =
@<<<<<<<< @>>>>>>
{ $name,
  $score }
.

Globals that control write#

Output through format is driven entirely by per-filehandle globals. Each is attached to the currently selected filehandle; changing them for another handle requires a select dance (see below):

  • $~ — name of the current format used for each record (defaults to the filehandle’s own name)

  • $^ — name of the current top-of-page format (defaults to the filehandle’s name with _TOP appended)

  • $= — page length in lines (default 60)

  • $- — lines remaining on the current page; write decrements it and triggers the top-of-page format when it reaches zero

  • $% — current page number, incremented automatically

  • $: — characters that fill mode (^) may break on (default " \n-")

  • $^L — string emitted before each top-of-page except the first (default "\f")

Under use English these are $FORMAT_NAME, $FORMAT_TOP_NAME, $FORMAT_LINES_PER_PAGE, $FORMAT_LINES_LEFT, $FORMAT_PAGE_NUMBER, $FORMAT_LINE_BREAK_CHARACTERS, and $FORMAT_FORMFEED.

Because these are per-handle, setting them for a handle other than the currently selected one needs select:

my $ofh = select $fh;
$~ = 'Report';
$^ = 'Report_TOP';
select $ofh;

Top-of-form#

When write decrements $- to zero, it emits $^L (except on the very first page), resets $- to $=, increments $%, and invokes the format named by $^. The default top-of-page format name is the filehandle’s name with _TOP appended, so declaring STDOUT_TOP suffices for writes through STDOUT.

Examples#

A minimal report with a header:

format STDOUT_TOP =
        Inventory
Name            Qty   Price
----------------------------
.
format STDOUT =
@<<<<<<<<<<<<<  @>>  @##.##
$name,          $qty, $price
.

for my $row (@rows) {
    ($name, $qty, $price) = @$row;
    write;
}

Switching formats for a non-selected handle:

open my $fh, '>', 'report.txt' or die $!;
my $ofh = select $fh;
$~ = 'Report';
$^ = 'Report_TOP';
select $ofh;
write $fh;

Fill mode with ~~ to drain a multi-line scalar one line at a time:

format STDOUT =
Note: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
      $note
~~    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
      $note
.

The ^ fields consume $note as they render; the ~~ line repeats until $note is empty.

Edge cases#

  • Lexical visibility: a format sees a my variable only when declared inside that variable’s scope. A top-level format cannot see my variables declared inside a subroutine; use package globals or declare the format inside the sub.

  • Quoted pictures: if you build a picture with eval from a double-quoted string, @name looks like an array interpolation. Escape it or use single quotes around the template.

  • A lone . is the terminator: a picture whose literal text would begin with . in column 1 must indent that line. This also bites format code sent through naive mail transports that cut at . on a line of its own.

  • Numeric overflow: a #-field narrower than the formatted number renders as #### rather than truncating silently.

  • Locale decimal point: if use locale was in effect when the format was declared, LC_NUMERIC picks the decimal character. Toggling use locale at write time does not change the picture.

  • Control characters inside a fixed-width text field are replaced by spaces to preserve column alignment.

  • Mixing print and write: legal on the same handle, but $- only tracks lines emitted by write. Adjust $- manually if interleaved print output consumes page lines you care about.

  • No footer mechanism: there is no $FORMAT_BOTTOM_NAME. Footers are done by hand — test $- before each write and emit the footer yourself when it reaches a threshold.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • write — render one record through the current format into the selected filehandle; the only way a declared format produces output

  • select — change which filehandle is current, required when setting $~, $^, $=, $-, $%, $:, or $^L for a handle other than STDOUT

  • $~ — current format name

  • $^ — current top-of-page format name

  • $= — page length

  • $- — lines left on the current page

  • $% — current page number

  • $: — fill-mode break characters

  • perlform.pod — full picture-line grammar, fill-mode rules, formline / $^A internals, and worked report examples