--- name: write signature: 'write FILEHANDLE' signatures: - 'write FILEHANDLE' - 'write EXPR' - 'write' since: 5.0 status: documented categories: ["I/O"] --- ```{index} single: write; Perl built-in ``` *[I/O](../perlfunc-by-category)* # write Render one record to a filehandle through its associated [`format`](format). `write` is the executor half of Perl's report-generation mechanism: it takes the picture declared by a [`format`](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`](syswrite) or the inverse of [`read`](read): `write` is strictly the picture-record executor. It has nothing to do with raw byte output. ## Synopsis ```perl write FILEHANDLE write EXPR write ``` ## What you get back `1` on success, [`undef`](undef) on failure (with [`$!`](../perlvar) 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`](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 `STDOUT` for `STDOUT`, format `REPORT` for a handle opened as `REPORT`). - The **top-of-page format** is the filehandle name with `_TOP` appended (`STDOUT_TOP`, `REPORT_TOP`), falling back to `top` in the current package. Both are overridable per-handle through [`$~`](../perlvar) (current format name) and [`$^`](../perlvar) (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`](select) dance: ```perl 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`](select): - [`$~`](../perlvar) — name of the record format for the selected handle. Read at every `write` call. - [`$^`](../perlvar) — name of the top-of-page format. Consulted when a new page begins. - [`$=`](../perlvar) — page length in lines. Default `60`. - [`$-`](../perlvar) — lines remaining on the current page. Decremented by every `write`. Set to `0` to force a page break on the next call. - [`$%`](../perlvar) — current page number. Incremented on each top-of-page. - [`$^L`](../perlvar) — string emitted before every top-of-page except the first. Default `"\f"` (form feed). - [`$:`](../perlvar) — characters on which fill-mode (`^`) fields may break. - [`$^A`](../perlvar) — the format accumulator, the buffer [`formline`](formline) writes into and `write` flushes. Rarely touched directly unless you are bypassing `write` with [`formline`](formline). `write` also writes through the PerlIO stack of the target handle, so [`$|`](../perlvar) (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 ([`$-`](../perlvar)). If it does not: 1. Emit [`$^L`](../perlvar) (form feed by default) — skipped on the very first page. 2. Run the top-of-page format named by [`$^`](../perlvar) to produce the page header. 3. Reset [`$-`](../perlvar) to [`$=`](../perlvar) and increment [`$%`](../perlvar). 4. 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: ```perl 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`](select) is needed if the default is acceptable: ```perl 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 [`$~`](../perlvar) on the selected handle. `local` confines the change to the current scope: ```perl sub print_summary { local $~ = "SUMMARY_FORMAT"; write; } ``` Force a page break by zeroing [`$-`](../perlvar) before the next call: ```perl $- = 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: ```perl my $handle_name = $verbose ? "LOG" : "STDOUT"; write $handle_name; ``` Interleaving [`print`](print) with `write`: legal, but [`$-`](../perlvar) only tracks `write` output. If a [`print`](print) burst consumes page rows you care about, decrement [`$-`](../perlvar) by hand: ```perl print "extra note: $msg\n"; $- -= 1; # keep the page counter honest write; ``` ## Edge cases - **Format not found**: if the format named by [`$~`](../perlvar) does not exist, `write` croaks with `Undefined format "NAME" called`. This is a fatal error, not a return-[`undef`](undef)-with-[`$!`](../perlvar) failure. - **Closed filehandle**: returns [`undef`](undef) and sets [`$!`](../perlvar). Under `use warnings` a `write() on closed filehandle` warning is emitted. - **Record taller than page**: if the record itself has more lines than [`$=`](../perlvar), `write` still emits all of its lines on one page — it does not split a single record across a page boundary. The oversize is silently tolerated. - **`_TOP` fallback**: if no `_TOP` format exists, `write` falls back to the format named `top` in the current package. This is rarely what you want for autovivified handles; set [`$^`](../perlvar) explicitly when it matters. - **Lexical variables in formats**: `my` variables 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 wraps `write` inside a subroutine and wonders why the report is blank — move the `format` declaration inside the sub, or use package globals for the argument-line expressions. - **Top-of-page triggers mid-record, not mid-page**: `write` checks 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_NUMERIC` and numeric fields**: if `use locale` is in effect when the format is declared, the decimal point in numeric fields follows the locale at declaration time — not at `write` time. 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 `\r` in fill-mode fields, where it forces a line break. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`format`](format) — declare the picture that `write` renders; the two are meaningless without each other - [`formline`](formline) — run one picture line against an argument list into [`$^A`](../perlvar) without any page tracking; the low-level primitive behind `write` - [`select`](select) — change which handle `write` targets when called without an argument, and the prerequisite for setting any of the `$~`, `$^`, `$=`, `$-` per-handle - [`print`](print) — free-form output when columnar reporting is overkill; may be interleaved with `write` on the same handle - [`$~`](../perlvar) — override the record format name for the selected handle - [`$-`](../perlvar) — lines left on the current page; set to `0` to force a new page before the next `write` - `perlform.pod` — full picture-line grammar, fill-mode rules, and worked report examples