--- name: say signature: 'say FILEHANDLE LIST' signatures: - 'say FILEHANDLE LIST' - 'say FILEHANDLE' - 'say LIST' - 'say' since: 5.10 status: documented categories: ["I/O"] --- ```{index} single: say; Perl built-in ``` *[I/O](../perlfunc-by-category)* # say Print a list of values followed by a newline. `say` is [`print`](print) with the output record separator forced to `"\n"` for that one call. It stringifies each item in `LIST`, joins them with [`$,`](../perlvar) (output field separator, usually empty), writes them to `FILEHANDLE`, and appends a literal `"\n"` — **not** the value of [`$\`](../perlvar). If `FILEHANDLE` is omitted, output goes to the currently selected handle (see [`select`](select)), which defaults to `STDOUT`. If `LIST` is omitted, [`$_`](../perlvar) is printed. `say` is a feature-gated built-in. It is available only when the `"say"` feature is enabled — automatic under `use v5.10` or higher, or explicit with `use feature 'say'` — or when called as `CORE::say`. ## Synopsis ```perl say LIST say FILEHANDLE LIST say {EXPR} LIST say ``` ## What you get back `1` on success, [`undef`](undef) on failure (with [`$!`](../perlvar) set). As with [`print`](print), the return value is rarely checked for `STDOUT` or `STDERR`. Check it when writing to a file, pipe, or socket where a write failure is a recoverable condition: ```perl say $fh $record or die "write to $path failed: $!"; ``` ## Default filehandle, default separators `say` reads the same global state as [`print`](print), with one deliberate exception: - The **currently selected filehandle**, changed with [`select`](select). `say LIST` writes there when no filehandle is given. Defaults to `STDOUT`. - [`$,`](../perlvar) — **output field separator**, inserted between list items. Defaults to the empty string, so `say 1, 2, 3` produces `"123\n"`, not `"1 2 3\n"`. - [`$\`](../perlvar) — **output record separator**. `say` **ignores [`$\`](../perlvar) entirely** and appends a literal `"\n"` instead. Setting [`$\`](../perlvar) has no effect on `say`. That last point is the whole reason `say` exists: one record, one newline, no fiddling with [`$\`](../perlvar). ## Examples Basic write to `STDOUT`: ```perl use feature 'say'; say "hello, world"; # "hello, world\n" ``` Write to a filehandle. Same indirect-object form as [`print`](print) — **no comma** between the filehandle and the list: ```perl open my $fh, ">", "out.txt" or die $!; say $fh "line 1"; say $fh "line 2"; close $fh; ``` Write to a filehandle held in an expression. Any filehandle more complex than a bareword or a plain scalar needs the `{EXPR}` block form: ```perl my @logs = (\*STDOUT, \*STDERR); say { $logs[$level] } "message"; ``` `say` joins list items with [`$,`](../perlvar) and then appends `"\n"` regardless of [`$\`](../perlvar): ```perl local $, = ", "; local $\ = ".\n"; # ignored by say say "apples", "pears", "plums"; # "apples, pears, plums\n" ``` No arguments — print [`$_`](../perlvar) plus a newline. The filehandle must be a bareword in this form; `say $fh;` would parse `$fh` as the content, not as the target: ```perl for (qw(alpha beta gamma)) { say; # "alpha\n", "beta\n", "gamma\n" } ``` List context applies to every argument: ```perl my @arr = (10, 20, 30); say @arr; # "102030\n" say scalar @arr; # "3\n" ``` ## Edge cases - **Feature gate**: without `use feature 'say'` or `use v5.10`, `say` is parsed as an ordinary subroutine call and will fail at compile time if no such sub is in scope. Use `CORE::say(...)` to call it unconditionally. - **No arguments with an explicit filehandle**: `say FH;` prints [`$_`](../perlvar) to `FH`, but only for **bareword** filehandles. `say $fh;` parses `$fh` as the content, not the target — write `say $fh $_;` if you mean that. This matches [`print`](print). - **[`$\`](../perlvar) is ignored, not overridden**: `say` does not set or [`local`](local)ise [`$\`](../perlvar). Other code that reads [`$\`](../perlvar) (including nested [`print`](print) calls) sees whatever value was already there. - **Filehandle-or-first-arg ambiguity**: same rule as [`print`](print). A bareword or a simple scalar immediately followed by a term (no comma) is taken as the filehandle. An expression returning a filehandle needs the block form: `say { $handles[0] } "x";`. - **`say (…)` parses as a function call**. `say (2+3)*4` prints `5` then discards `*4`. Parenthesise the whole argument list, or prefix with `+`: ```perl say((2+3)*4); # "20\n" say +(2+3)*4; # "20\n" ``` - **Closed filehandle**: returns [`undef`](undef) and sets [`$!`](../perlvar) to `"Bad file descriptor"`. Under `use warnings` a `say() on closed filehandle` warning is emitted. - **Encoding layers**: `say` writes through the handle's PerlIO stack exactly like [`print`](print). A handle with a `:utf8` or `:encoding(...)` layer encodes on the way out; the appended newline is a single `"\n"` byte and is encoded by the same layer. A wide-character string written to a bytes-mode handle triggers a `Wide character in say` warning. - **Autoflush**: `say` buffers through PerlIO like [`print`](print). Set [`$|`](../perlvar) on the selected handle for line-buffered output. - **`SIGPIPE`**: writing to a closed pipe or socket raises `SIGPIPE`. The default action terminates the process; install a handler to convert it into a normal write failure. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`print`](print) — same targeting and separator rules, but appends [`$\`](../perlvar) (empty by default) instead of a forced newline - [`printf`](printf) — formatted output; does not append a newline, you put one in the format string - [`select`](select) — change which filehandle the no-argument form of `say` writes to - [`$,`](../perlvar) — output field separator inserted between list items; `say` honours it - [`$\`](../perlvar) — output record separator; `say` **ignores it** and appends `"\n"` instead - [`$|`](../perlvar) — autoflush flag for the currently selected handle