Version 14 of puts

Updated 2006-01-06 11:56:48

puts - Write to a channel

 puts ?-nonewline? ?channelId? string  

http://www.purl.org/tcl/home/man/tcl8.4/TclCmd/puts.htm

Writes the characters given by string to the channel given by channelId. ChannelId must be a channel identifier such as returned from a previous invocation of open or socket. It must have been opened for output. If no channelId is specified then it defaults to stdout. Puts normally outputs a newline character after string, but this feature may be suppressed by specifying the -nonewline switch. The latter is necessary when Working with binary data.

Newline characters in the output are translated by puts to platform-specific end-of-line sequences according to the current value of the -translation option for the channel (for example, on PCs newlines are normally replaced with carriage-return-linefeed sequences; on Macintoshes newlines are normally replaced with carriage-returns). See the fconfigure manual entry for a discussion on ways in which fconfigure will alter output.

Tcl buffers output internally, so characters written with puts may not appear immediately on the output file or device; Tcl will normally delay output until the buffer is full or the channel is closed. You can force output to appear immediately with the flush command. When the output buffer fills up, the puts command will normally block until all the buffered data has been accepted for output by the operating system. If channelId is in nonblocking mode then the puts command will not block even if the operating system cannot accept the data. Instead, Tcl continues to buffer the data and writes it in the background as fast as the underlying file or device can accept it. The application must use the Tcl event loop for nonblocking output to work; otherwise Tcl never finds out that the file or device is ready for more output data. It is possible for an arbitrarily large amount of data to be buffered for a channel in nonblocking mode, which could consume a large amount of memory. To avoid wasting memory, nonblocking I/O should normally be used in an event-driven fashion with the fileevent command (don't invoke puts unless you have recently been notified via a file event that the channel is ready for more output data). (From: Tcl Help)


The only value string may not always take is "-nonewline". If you want to print the string "-nonewline" with a newline, you can only do

 puts -nonewline -nonewline\n

(where the \n neutralizes the effect of the first -nonewline, which is the switch; but I never needed that so far;-) or, as Andreas Leitgeb pointed out,

 puts stdout $string

where string may have any value, including "-nonewline".


Darren New recently pointed out in comp.lang.tcl that:

 > Last I looked,
 >   puts $x
 > actually called write() twice, one for $x, one for \n. This would leave
 > the possibility of getting two lines of data and two newlines.
 >   puts -nonewline $x\n
 > is what I use to prevent this.

This was in the context of two different programs/procs writing to the same log file...


puts from a tclsh may, when piped through more, raise

 error writing "stdout": broken pipe
    while executing
 "puts "<$tok> name=\"[string range $line 5 end]\">""
    ("while" body line 9)
    invoked from within...

No big problem but ugly - therefore I routinely add the one-liner

   proc puts! s {catch {puts $s}}

and call puts! in place of the real thing. (RS) A variation, which requires that you only use simple puts (to stdout, no -nonewline), but then is transparent (i.e. in your normal script you can just call normal puts):

 rename puts tcl::puts
 proc puts string {if [catch {tcl::puts $string}] exit}

Note that puts has an artifact from Tcl 6.4 (!) which is undocumented. If the puts command is invalidly called with 3 arguments, one gets the following error:

 % puts stdout foo bar
 bad argument "bar": should be "nonewline"

This is due to the fact that back in ancient times, the syntax for the -nonewline was not a leading argument, but a trailing string value of "nonewline".


puts workaround shows how to overload puts, so stdout and stderr (which are not available on iPaq) are rerouted to a text widget.


Tcl 8.3 on Windows had a puts performance problem, when data was written to a file file. The problem was that every buffer write caused a flush of the disk cache. The workaround in 8.3 was to do (once, at beginning of script):

    fconfigure stdout -buffering full -buffersize 262144

so that there were few disk writes performed. (Thanks KBK and the Tcl chatroom for the quick answer! RS)


Silas - 2006-01-06 - You can print colors or bold text with puts (at least, in a Linux shell which supports that (like xterm or rxvt)).

You should use the ANSI standard (ISO) 6429 to make that. In ANSI color control, RS uses that to color pieces of text in a text widget.

Here goes a little example:

 % puts "\033\[01;32mFoo\033\[0mbar"
 Foobar

The Foo is bold green.

'Any ISO 6429 url about?'


Tcl syntax help - Arts and crafts of Tcl-Tk programming - Category Command