我正在尝试实现实现接口的类以及结果对象的序列化,但遇到了 objdefine 错误消息(使用 Tcl 8.5 + TclOO 1.0.x)。
我想我对原因有一些了解,但除了重新编译 TclOO 和修补之外,我不确定是否有其他解决方法。
我做了一个最小的例子:
package require Tcl 8.5
package require TclOO
# https://wiki.tcl-lang.org/page/Serializing+TclOO+objects#mkup_code_2
::oo::class create ::oo::serializable {}
# https://wiki.tcl-lang.org/page/Extending+TclOO+with+metaclasses#mkup_code_10
::oo::class create ::oo::interface {
superclass ::oo::class
mixin ::oo::InterfaceMixin
self method create {name args} {
set instance [next $name {*}$args]
# this line appears to cause the problem
::oo::define $instance superclass -append [self]
return $instance
}
}
namespace eval ::csh::oo {}
# creates instances with createWithNamespace
::oo::class create ::csh::oo::nclass {
superclass ::oo::class
mixin ::oo::InterfaceMixin
...
}
::oo::interface create ::SpecialMethods {
}
::csh::oo::nclass create ::ABC {
superclass ::oo::serializable ::SpecialMethods
}
set abc [::oo::serializable new]
# error in Tcl 8.5 + TclOO 1.0.x
# ok in Tcl 8.6.12
::oo::objdefine $abc class ::ABC
# error: "may not change a non-class object into a class object"
可以更改
::oo::interface
类以使 ::oo::objdefine
工作吗?
在 GDB 下运行 TCLOO 1.0.2 显示:
tclOODefineCmds.c:1188
当拨打 oPtr->classPtr
电话时,NULL
为 objdefine
。
这听起来可能是突变安全条件中的一个错误。这是不幸的;单独的 TclOO 已存档,因为它甚至不会跟踪 Tcl 8.6 版本 TclOO 中的所有错误修复(更不用说更高 Tcl 版本中的新功能)。由于代码适用于 8.6.12,因此建议的修复方法是不要使用 Tcl 的生命周期终止版本系列; 8.6 收到错误修复,8.5(以及紧密链接的代码,例如独立的 TclOO)则没有。
这不是您想要的答案,但这是您会得到的答案。 (我对追查 bug 何时被修复不感兴趣,更不用说将修复程序向后移植到我永远不会发布的东西了。)