if 0 {Richard Suchenwirth 2003-02-28 - In a wish on the iPAQ, a plain puts raises the error
cannot find channel named "stdout"
But as puts is a frequent and useful command, we want to have it working. So here�s a substitute that redirects the output to a specified text widget, if the (implicit or explicit) channel name is stdout or stderr, but else calls the original puts, which was renamed into the ::tcl namespace: }
proc redef_puts w { set ::putsw $w if ![llength [info command ::tcl::puts]] { rename puts ::tcl::puts proc puts args { set la [llength $args] if {$la<1 || $la>3} { error "usage: puts ?-nonewline? ?channel? string" } set nl \n if {[lindex $args 0]=="-nonewline"} { set nl "" set args [lrange $args 1 end] } if {[llength $args]==1} { set args [list stdout $args] } foreach {channel s} $args break set s [join $s] ;# (1) prevent braces at leading/tailing spaces if {$channel=="stdout" || $channel=="stderr"} { $::putsw insert end $s$nl } else { set cmd ::tcl::puts if {$nl==""} {lappend cmd -nonewline} lappend cmd $channel $s eval $cmd } } } }
RS added fix (1), because without join the argument might still come brace-quoted.
Lars H: The (roughly) Tcl 7.4 interpreter embedded in the (recently retired) Alpha7 [L1 ] text editor suffered from a similar problem. In that case the bug was much nastier: a simple [puts stdout "whatever"] would crash the entire application, since there was a bug in its code for emulating a console window.
I wrote a package I called terminal ([L2 ], also distributed with the Alpha text editor as of v7.6) to work around this problem. Besides a redefinition of puts similar to the above, it also features a set of commands that make it convenient to print messages smaller than a line. The commands
for {set n 1} {$n<=10} {incr n} { terminal::print_word space "\[$n" none if {$n % 7 == 0} then { terminal::print_word newline "And that's divisible by 7." none } terminal::print_word none "\]" space if {$n % 5 == 0} then { terminal::print_word newline "Interruption!" newline } }
would print the following to "the terminal":
[1] [2] [3] [4] [5] Interruption! [6] [7 And that's divisible by 7.] [8] [9] [10] Interruption!
The first and third arguments of [terminal::print_word] request that the string in the second argument is separated from surrounding text by a certain degree of whitespace. Note that there are no stray spaces at the beginning or end of lines.
Oh, yes. I should also point out that the package is written so that it works also on a standard tclsh (or whatever) shell. The main point is to provide the terminal::print_word etc. commands -- the puts workaround was a minor point.