実行中のコードが画面に出力され、それを root.tk.eval() で呼び出している場合、それをキャプチャすることはできません。ただし、tcl コードで「puts」が行うことを再定義して、必要に応じて実行させることができます。これは Tcl の優れた点の 1 つです。予約語はありません。
Tcl インタープリターで「puts」という名前の proc を作成するだけですが、インターフェイスがまったく同じであることを確認してください (つまり、「-nonewline」を尊重し、ファイルに書き込むことができるなど)。puts が通常画面に出力する場合、代わりに、ソケットへの書き込みや、出力するはずの文字列を単に返すなど、必要なことを実行させることができます。
大まかに(テストされておらず、 -nonewline のケースを無視しています):
root.tk.eval('''
rename puts original_puts
proc puts {args} {
if {[llength $args] == 1} {
return "=> [lindex $args 0]"
} else {
eval original_puts $args
}
}
''')
foo = root.tk.eval('puts "hello, world"')
print foo
=> hello, world
標準の "puts" ステートメントを想定している Tcl コードを壊さないようにするには、少し注意が必要ですが、それほど難しいことではありません。1 つの引数、"-nonewline" の最初の引数、および 2 つの引数 (ファイル記述子と文字列) の特殊なケースがあることを確認してください。
eval を呼び出して 2 つの puts ステートメントを実行したり、puts の後に他のコードを実行したりすると、eval の結果が最後のステートメントの結果になるため、複雑になる可能性があります。ただし、その出力をグローバル変数にバッファリングし、eval を実行するたびにその変数の結果を返すことで、これを回避できます。
ですから、少し枠にとらわれずに考えてみると、解決策が見つかります。Tcl は非常に柔軟です。