say#
Print a list of values followed by a newline.
say is print with the output record separator forced to "\n"
for that one call. It stringifies each item in LIST, joins them
with $, (output field separator, usually empty), writes them to
FILEHANDLE, and appends a literal "\n" — not the value of
$\. If FILEHANDLE is omitted, output goes to the currently
selected handle (see select), which defaults to STDOUT.
If LIST is omitted, $_ 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#
say LIST
say FILEHANDLE LIST
say {EXPR} LIST
say
What you get back#
1 on success, undef on failure (with $! set). As with 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:
say $fh $record
or die "write to $path failed: $!";
Default filehandle, default separators#
say reads the same global state as print, with one
deliberate exception:
The currently selected filehandle, changed with
select.say LISTwrites there when no filehandle is given. Defaults toSTDOUT.$,— output field separator, inserted between list items. Defaults to the empty string, sosay 1, 2, 3produces"123\n", not"1 2 3\n".$\— output record separator.sayignores$\entirely and appends a literal"\n"instead. Setting$\has no effect onsay.
That last point is the whole reason say exists: one record, one
newline, no fiddling with $\.
Examples#
Basic write to STDOUT:
use feature 'say';
say "hello, world"; # "hello, world\n"
Write to a filehandle. Same indirect-object form as print — no
comma between the filehandle and the list:
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:
my @logs = (\*STDOUT, \*STDERR);
say { $logs[$level] } "message";
say joins list items with $, and then appends "\n" regardless
of $\:
local $, = ", ";
local $\ = ".\n"; # ignored by say
say "apples", "pears", "plums"; # "apples, pears, plums\n"
No arguments — print $_ plus a newline. The filehandle must be a
bareword in this form; say $fh; would parse $fh as the content,
not as the target:
for (qw(alpha beta gamma)) {
say; # "alpha\n", "beta\n", "gamma\n"
}
List context applies to every argument:
my @arr = (10, 20, 30);
say @arr; # "102030\n"
say scalar @arr; # "3\n"
Edge cases#
Feature gate: without
use feature 'say'oruse v5.10,sayis parsed as an ordinary subroutine call and will fail at compile time if no such sub is in scope. UseCORE::say(...)to call it unconditionally.No arguments with an explicit filehandle:
say FH;prints$_toFH, but only for bareword filehandles.say $fh;parses$fhas the content, not the target — writesay $fh $_;if you mean that. This matchesprint.$\is ignored, not overridden:saydoes not set orlocalise$\. Other code that reads$\(including nestedprintcalls) sees whatever value was already there.Filehandle-or-first-arg ambiguity: same rule as
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)*4prints5then discards*4. Parenthesise the whole argument list, or prefix with+:say((2+3)*4); # "20\n" say +(2+3)*4; # "20\n"
Closed filehandle: returns
undefand sets$!to"Bad file descriptor". Underuse warningsasay() on closed filehandlewarning is emitted.Encoding layers:
saywrites through the handle’s PerlIO stack exactly likeprint. A handle with a:utf8or: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 aWide character in saywarning.Autoflush:
saybuffers through PerlIO likeprint. Set$|on the selected handle for line-buffered output.SIGPIPE: writing to a closed pipe or socket raisesSIGPIPE. 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— same targeting and separator rules, but appends$\(empty by default) instead of a forced newlineprintf— formatted output; does not append a newline, you put one in the format stringselect— change which filehandle the no-argument form ofsaywrites to$,— output field separator inserted between list items;sayhonours it$\— output record separator;sayignores it and appends"\n"instead$|— autoflush flag for the currently selected handle