write#
Render one record to a filehandle through its associated format.
write is the executor half of Perl’s report-generation mechanism: it
takes the picture declared by a format, plugs the values from the
matching argument lines into the fields, and emits the resulting
lines to FILEHANDLE. It also tracks the page: when not enough lines
remain, it writes a form feed, runs the top-of-page format, and then
writes the record. write is the only way a declared format
produces output; a format is inert until write references it.
Do not confuse this with syswrite or the inverse of read:
write is strictly the picture-record executor. It has nothing to do
with raw byte output.
Synopsis#
write FILEHANDLE
write EXPR
write
What you get back#
1 on success, undef on failure (with $! set). A failure here
is typically either a closed handle or an I/O error on the underlying
write — not “format not found,” which croaks rather than returning
undef.
How write picks the format#
Every filehandle has two format slots: the record format and the top-of-page format. By default:
The record format is the format whose name matches the filehandle (format
STDOUTforSTDOUT, formatREPORTfor a handle opened asREPORT).The top-of-page format is the filehandle name with
_TOPappended (STDOUT_TOP,REPORT_TOP), falling back totopin the current package.
Both are overridable per-handle through $~ (current format name)
and $^ (current top-of-page format name). These variables act on
the currently selected handle, so changing them for anything
other than STDOUT requires a select dance:
my $ofh = select REPORT;
$~ = "My_Format";
$^ = "My_Top";
select $ofh;
If FILEHANDLE is omitted, write targets the currently selected
handle (default STDOUT). If the argument is an EXPR rather than a
bareword, the expression is evaluated and its string value is looked
up as the filehandle name at runtime.
Global state it touches#
write reads and updates a cluster of per-handle format variables.
All are per-filehandle, reached via select:
$~— name of the record format for the selected handle. Read at everywritecall.$^— name of the top-of-page format. Consulted when a new page begins.$=— page length in lines. Default60.$-— lines remaining on the current page. Decremented by everywrite. Set to0to force a page break on the next call.$%— current page number. Incremented on each top-of-page.$^L— string emitted before every top-of-page except the first. Default"\f"(form feed).$:— characters on which fill-mode (^) fields may break.$^A— the format accumulator, the bufferformlinewrites into andwriteflushes. Rarely touched directly unless you are bypassingwritewithformline.
write also writes through the PerlIO stack of the target handle, so
$| (autoflush on the selected handle) still applies.
Top-of-form processing#
Before emitting the record, write checks whether the record fits in
the lines remaining on the page ($-). If it does not:
Emit
$^L(form feed by default) — skipped on the very first page.Run the top-of-page format named by
$^to produce the page header.Emit the record.
On the very first write to a handle, step 1 is skipped so the
output does not begin with a form feed.
Examples#
Basic report with a header:
format STDOUT_TOP =
Passwd File
Name Login Office Uid Gid Home
------------------------------------------------------------------
.
format STDOUT =
@<<<<<<<<<<<<<<<<<< @||||||| @<<<<<<@>>>> @>>>> @<<<<<<<<<<<<<<<<<
$name, $login, $office,$uid,$gid, $home
.
while (my @row = getpwent) {
($name, $login, $uid, $gid, $office, $home) = @row[0,0,2,3,5,7];
write;
}
Write to a named filehandle. The format name defaults to the handle
name; no select is needed if the default is acceptable:
open my $fh, ">", "report.txt" or die $!;
format REPORT =
@<<<<<<<<<<<<<< @>>>>>>>
$item, $count
.
# rebind the glob so REPORT refers to $fh
*REPORT = *$fh;
for my $r (@records) {
($item, $count) = @$r;
write REPORT;
}
close $fh;
Switch format at runtime by setting $~ on the selected handle.
local confines the change to the current scope:
sub print_summary {
local $~ = "SUMMARY_FORMAT";
write;
}
Force a page break by zeroing $- before the next call:
$- = 0; # next write starts a new page
write;
write EXPR picks the handle at runtime from a string — useful when
the target is data-driven:
my $handle_name = $verbose ? "LOG" : "STDOUT";
write $handle_name;
Interleaving print with write: legal, but $- only
tracks write output. If a print burst consumes page rows you
care about, decrement $- by hand:
print "extra note: $msg\n";
$- -= 1; # keep the page counter honest
write;
Edge cases#
Format not found: if the format named by
$~does not exist,writecroaks withUndefined format "NAME" called. This is a fatal error, not a return-undef-with-$!failure.Closed filehandle: returns
undefand sets$!. Underuse warningsawrite() on closed filehandlewarning is emitted.Record taller than page: if the record itself has more lines than
$=,writestill emits all of its lines on one page — it does not split a single record across a page boundary. The oversize is silently tolerated._TOPfallback: if no<HANDLE>_TOPformat exists,writefalls back to the format namedtopin the current package. This is rarely what you want for autovivified handles; set$^explicitly when it matters.Lexical variables in formats:
myvariables declared outside a format are not visible inside it unless the format is declared within the lexical scope of those variables. This bites anyone who wrapswriteinside a subroutine and wonders why the report is blank — move theformatdeclaration inside the sub, or use package globals for the argument-line expressions.Top-of-page triggers mid-record, not mid-page:
writechecks page room once per record. A record that starts near the bottom of the page will either fit in full or trigger top-of-page before being written; it never straddles.LC_NUMERICand numeric fields: ifuse localeis in effect when the format is declared, the decimal point in numeric fields follows the locale at declaration time — not atwritetime. Switching locales after the format is compiled does not change the separator.Control characters in text fields are replaced with spaces so they cannot scramble column alignment. The sole exception is
\rin fill-mode fields, where it forces a line break.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
format— declare the picture thatwriterenders; the two are meaningless without each otherformline— run one picture line against an argument list into$^Awithout any page tracking; the low-level primitive behindwriteselect— change which handlewritetargets when called without an argument, and the prerequisite for setting any of the$~,$^,$=,$-per-handleprint— free-form output when columnar reporting is overkill; may be interleaved withwriteon the same handle$~— override the record format name for the selected handle$-— lines left on the current page; set to0to force a new page before the nextwriteperlform.pod— full picture-line grammar, fill-mode rules, and worked report examples