gyn

Win32下的Perl,无用的select,停滞的Tk,结束吧....

Tcl中的输出重定向

有时候重定向是得到执行信息的必要手段,比如我在调试某个程序时需要将调试的输出结果存放到某个文件中以便于日后查看。

1.close stdout

2.set stdout [open out.txt w]

我关闭并重定义了 stdout ,使其成为某个被打开文件的 channel ,那么执行 puts 事实上是完成了对于文本的写操作。在还有一些情况中,是将 stdout 的结果显示到比如 text 这样的 Tk 组件上,以上的办法显然是无能为力了。作为 stdout 本身必须是一个 channel ,它不能作为一个变量或者其他什么的,所以一个替代的办法是使用 Memchan 模块,以下是在 tcl 的 wiki 上的一段代码。

1.package require Tk

2.package require Memchan

 3.

4.text .t

5..t tag configure stdout -font {Courier 10}

6..t tag configure stderr -font {Courier 10} -foreground red

7.pack .t

 8.

9.# install new stdout

10.close stdout

11.set stdout [fifo]

12.fileevent $stdout readable ".t insert end \[read $stdout\] stdout; .t see end"

13.

14.# install new stderr

15.close stderr

16.set stderr [fifo]

17.fileevent $stderr readable ".t insert end \[read $stderr\] stderr; .t see end"

18.

19.# test it

20.puts "this is stdout"

21.puts stderr "this is stderr"

通过 fileevent ,以上程序提供了一个非常优雅的重定向办法,但是带程序的作者还附加了一句话。事实上,这段代码是无法正确执行的,因为重定义的 stdout 并没有被创建,而且该 bug 似乎至今没有被修复。

warning: the current distribution has a bug, I have submitted a patch to the author

在 cucumber1.1.1 的 tclsh 中需要将 puts 的内容如同 return 的结果一样写入 text 文本组件中,但考虑到循环打印的情况,又不能仅仅将 puts 当做 return 来对待,从而导致执行代码的中止。我的解决办法依然是使用 rename ,在 puts 之前注入代码。

1.con eval {

 2.   rename puts _puts

 3.   proc puts {args} {

 4.       putsstdout $args

 5.   }

6.}

7.interp alias con putsstdout {} putsstdout

8.proc putsstdout {msg} {

 9.   .console insert end "$msg\n"

10.   .console see end

11.}

模拟 tclsh 的过程是发生在名为 con 的子解析器里的,需要使用 alias 将子解析器中的数据交由主解析器中的函数来更新 .console 中的显示。以上代码中的第 4 行便是重定向的关键所在,当然我们还可以将数据以传统形式输出到 stdout 中,这就看具体情况而定了。事实上,这种办法并不算是真正意义上的重定向,但是得到了相同的效果。

posted on 2009-09-25 14:50 gyn_tadao 阅读(5679) 评论(0)  编辑 收藏 引用 所属分类: TclTk

只有注册用户登录后才能发表评论。
<2009年12月>
日一二三四五六
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

常用链接

留言簿(15)

随笔分类(126)

随笔档案(108)

相册

搜索

最新评论

阅读排行榜

评论排行榜