1

我使用了一个能够运行 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
} 
4

2 回答 2

1

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

于 2014-09-07T00:28:49.440 回答
0

有几个地方你做错了。即使什么都不做,您也必须支持,并且您必须返回从您的实现中写入的字节数(幸运的是,这对您来说是微不足道的)。watchwrite

这也是隐藏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对变量名与变量使用的严格规定——并且您可能会遇到测试问题,因为 Tcl 的通道(除非去终端)默认为完全缓冲,这使得在这种情况下没有意义。

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<<

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

>>敏捷的棕狐跳过懒惰的狗。
你好,伙计!
<<
于 2014-09-07T15:56:17.740 回答