Oop TclOO:如何转发到变量?
我已经了解到,我可以Oop TclOO:如何转发到变量?,oop,tcl,Oop,Tcl,我已经了解到,我可以将命令转发到构造函数中创建的对象。据我所知,这些对象作为命令存在于实例名称空间中。 但是,如果我要转发的对象已作为参数从外部传递给构造函数,而不是在构造函数内部创建,我该怎么办? 将其存储为变量不起作用,因为forward仅适用于命令。我曾想过使用interp alias创建一个可以转发的“本地”命令,但我必须承认,命令与变量的整个概念对我来说仍然有些麻烦(我更习惯于Python或C) 有关说明,请参见以下示例: oo::class A { method hello {}
将命令转发到构造函数中创建的对象。据我所知,这些对象作为命令存在于实例名称空间中。
但是,如果我要转发的对象已作为参数从外部传递给构造函数,而不是在构造函数内部创建,我该怎么办?
将其存储为变量不起作用,因为forward
仅适用于命令。我曾想过使用interp alias
创建一个可以转发的“本地”命令,但我必须承认,命令与变量的整个概念对我来说仍然有些麻烦(我更习惯于Python或C)
有关说明,请参见以下示例:
oo::class A {
method hello {} {
puts "Hello, from [self]"
}
}
oo::class B {
constructor {some_a3} {
A create a1
A create a2
# store some_a3
variable a3
set a3 $some_a3
# this won't work because forward works on commands not variables
}
forward var1 a1
forward var2 a2
forward var3 ???
}
因此,它可以像这样使用:
set a3 [A new]
set b [B new $a3]
$b var1 hello
$b var2 hello
$b var3 hello
PS:如果我的方法完全偏离了轨道(像un TCL),我愿意听取其他建议。:) 不能直接转发到变量;转发机制非常简单。但是您可以在构造函数中创建转发。这是通过oo::objdefine
命令完成的,该命令对对象进行每个实例的更改,几乎就像更改最特定的子类一样(除了它根本不是类;它实际上就是实例)
在这种情况下,传入的对象将不属于B
的实例;您必须手动删除它。另外,您可能需要确保命令名是完全限定的。默认情况下,TclOO将对象作为完全限定名返回,但大多数其他Tcl命令通常不限定(例如,在您的脚本和我的脚本中几乎所有的命令)。Tcl的命令与其变量完全不同。存在的交叉是通过apply
命令与lambda应用程序进行的,但这在语法上是完全不同的。我们知道这一点,我们正在考虑缩小差距的步骤(但不是完全缩小差距;我们喜欢区分名称和用途)。对一个评论领域来说,对这个问题进行更深入的讨论太长了,很难就这个话题给出完整的答案……谢谢。要了解您关于手动删除实例的观点:我将如何做到这一点?我假设在B的析构函数中调用'my var3 destroy'是正确的吗?手动删除实例将是$a3 destroy
。如果要在B
的析构函数中执行此操作,则应将其保存在变量中。但是当所有权关系存在时,在构造函数中构建子实例更简单。我的问题只是为了澄清。我正在处理一个类似于树的结构,并试图处理从子级到父级的引用(从父级到子级的所有权则相反)。注意:您将如何处理动态添加的子项(即,不是在构建父项时)?您可以随时使用oo::objdefine
(甚至oo::define
);构造器在这里并不是很特别,您可以很容易地将对象集合保存在实例变量中。需要注意的主要一点是,如果要处理多个子对象,可能不希望将每个子对象都公开为其自己的转发方法。(不知道如何做到这一点;答案取决于真实的细节,而不是样本中假设的细节。)例如,您可能会考虑将某些方法“转发”给所有子级(使用帮助器方法?),您甚至可以在析构函数中使用oo::objdefine
,但我不建议这样做(事实上,这完全没有意义!)
oo::class B {
constructor {some_a3} {
A create a1
A create a2
##### The next line does the magic #####
oo::objdefine [self] forward var3 $some_a3
# The double-spaces are for clarity only; they separate the part that belongs
# to the call to the defining command, the forwarded method declaration, and
# what it is being forwarded to. Two spaces is as good as one in Tcl command
# invocations...
}
forward var1 a1
forward var2 a2
}