在TCL中为特定应用创建Chan

时间:2014-09-06 23:59:31

标签: tcl channel puts

我使用能够运行TCL的应用程序,应用程序本身是用C ++编写的(速记10)我相信我推动它远远超出它的预期目标。和大多数编程语言一样好的工具。然而,这提出了一个独特的问题,TCL原生的一些项目不包括在内,所以我必须找到创造性的方法来做我想要完成的事情。 - 后面的故事......其中一个主要缺点是没有标准或其他常规频道。我知道有一种方法可以创建一个,但我很难过。我找到了以下代码,并试图让它工作,但我得到一个错误。我想用于标准输出的文件路径是:

#FilePath of output ---> [sh_window exedir]IO_Text/stdout

oo::class create stdout {
    variable var
    constructor {varName} {
        my eval [list upvar \#0 $varName var]
    }
    method initialize {ch mode} {
        if {$mode ne "write"} {error "can't handle reading"}
        return {finalize initialize write}
    }
    method watch {ch events} {
        # Must be present but we ignore it because we do not
        # post any events
    }
    method finalize {ch} {
        my destroy
    }
    method write {ch bytes} {
        append var $bytes
        # Return the empty string, as we are swallowing the bytes
        return ""
    }
}

# Now we create an instance...
set string "The quick brown fox jumps over the lazy dog.\n"
set ch [chan create write [stdout new $string]]

- 运行此操作时出现以下错误:

chan handler "::oo::Obj12" does not support all required methods

我目前使用的解决方法如下。但我知道这太可怕了!

rename puts _puts;
proc puts {WInfo} {
set chan [open "[sh_window exedir]IO_Text/stdout" a+]
_puts $chan $WInfo; close $chan
} 

2 个答案:

答案 0 :(得分:1)

您正缺少强制watch子命令的实现,如refchan documentation中所述。这就是为什么你得到关于不支持所有方法的错误。该示例显示了可以复制的虚拟存根。

答案 1 :(得分:0)

有几个地方出了问题。您必须支持watch,即使无所事事,您必须返回从write实施中写入的字节数(幸运的是,这是你要做的很简单。

这也是在类实例的构造函数中隐藏对chan create的调用的好时机;没有办法使用其他方法创建的对象,所以我们不妨松开它。 (你不能在Java中这样做,而不用工厂。)

oo::class create stdout {
    variable var
    constructor {varName} {
        set s [list upvar \#0 $varName var]
        namespace eval [namespace current] $s
    }
    method initialize {ch mode} {
        if {$mode ne "write"} {error "can't handle reading"}
        return {finalize initialize write watch}
    }
    method watch {ch events} {
        # Must be present but we ignore it because we do not post any events
    }
    method finalize {ch} {
        my destroy
    }
    method write {ch bytes} {
        append var $bytes
        return [string length $bytes]
    }
    # Magic! Define a method on the 'stdout' class object itself
    self method new {varName} {
        set obj [next $varName]
        return [chan create write $obj]
    }
    # Stop normal code from creating named instances
    self unexport create
}

最后,你在测试代码中调用了一个奇怪的变量名--Tcl&#39> 严格关于变量名和变量用法 - 你可能会遇到测试问题因为Tcl&#39 ; s通道(除了去往终端时)默认为完全缓冲,在这种情况下没有任何意义。

set myString "The quick brown fox jumps over the lazy dog.\n"
set ch [stdout new myString]
fconfigure $ch -buffering none
puts $ch "Howdy, pardner!"
puts >>$myString<<

当我尝试这个时,我得到了这个输出:

>>The quick brown fox jumps over the lazy dog.
Howdy, pardner!
<<