Tcl 从超类调用方法

Tcl 从超类调用方法,tcl,Tcl,我目前正在使用TclOO在Tcl中编写一个IRC库 现在我想实现输出队列,因为大多数IRC服务器不喜欢一次发送太多文本 超类有一个方法send,它只向套接字写入内容: oo::class ::irc::core { method send {text} { variable socket puts $socket $text } # ... } 为了实现队列,我决定扩展我的核心类并覆盖send: oo::class ::irc::queu

我目前正在使用TclOO在Tcl中编写一个IRC库

现在我想实现输出队列,因为大多数IRC服务器不喜欢一次发送太多文本

超类有一个方法
send
,它只向套接字写入内容:

oo::class ::irc::core {
    method send {text} {
        variable socket
        puts $socket $text
    }
    # ...
}
为了实现队列,我决定扩展我的核心类并覆盖
send

oo::class ::irc::queue {
    method send {text} {
        # For this example, we just delay it.
        after 50 [list [namespace which my] DrainQueue $text]
    }
    method DrainQueue {text} {
        # Now call [send] from ::irc::core
        my send $text
    }
}
这显然行不通


TL;DR在Java中,我会使用
super.Method()
,TclOO的等价物是什么?

在脚本级别,没有任何东西允许您使用超类视图调用任意方法。最好使用协同程序来构造代码,这样可以延迟代码的执行。然后你可以写下:

method send {text} {
    after 50 [info coroutine]
    yield
    next $text
}

可供替代的 要编写没有这个的东西,可能最简单的方法是将实际发送者放在超类中一个不同的私有方法中,并从public方法转发给它。然后,您可以根据需要覆盖和调用

oo::class ::irc::core {
    method Send {text} {
        variable socket
        puts $socket $text
    }
    forward send my Send
    # ...
}

oo::class ::irc::queue {
    method send {text} {
        after 50 [list [namespace which my] DrainQueue $text]
    }
    method DrainQueue {text} {
        my Send $text
    }
}   

真实的方式(对于C黑客) C API可以通过向对象中添加a来支持这种行为,但这在功能上不向脚本公开(在[incr Tcl]4中除外),并且它的缺点是必须限制合法方法名称的空间(虽然我为将来的扩展保留了一些东西,例如多单词名称,但目前基本上是无限的)。我猜您不会马上想到方法名称映射是处理此类问题的一种方法,但这是该机制的预期用途


将映射器API公开给脚本也许应该是我议程上的重点;到目前为止,它已经落后了很长一段时间(远低于子方法和垃圾收集…

您是否想过使用
next

也许这会有所帮助(TCL 8.6),如果我理解您的要求,下一步应该完成工作。
请参阅下面的小代码:
oo::class创建一个{
方法moo{}{
放上“我是一体的”
}
}
oo::类创建两个{
超类一
方法moo{}{
放上“我是两个”
下一步
}
}
两个创建foo
富慕 退出

输出为:
我两岁

我是一个

下一个调用超类方法moo

实际的代码有点复杂,我尝试组合消息,每秒发送一条消息。其他一些部分也期望
发送
会立即返回。我可以从
DrainQueue
调用
发送
,并检查它是否是从
DrainQueue调用的队列
。我仍然不喜欢。问题是,你不能在任意深度启动调用;当你调用一个方法时,它将从
信息对象调用
描述的第一项开始。也许应该添加此功能。也许你不应该以需要它的方式编写代码…:p