Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop TclOO:如何转发到变量?_Oop_Tcl - Fatal编程技术网

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
}