2014-11-05 205 views
1

让怙我们有两个类,如下所示:TclOO:访问嵌套对象

oo::class create InsideThing { 
    constructor {} { 
     puts "Made a [self] that is an InsideThing" 
    } 
    destructor { 
     puts "Deleted a [self] that is an InsideThing" 
    } 
    method echo {text} { 
     puts "[self]: $text" 
    } 
} 
oo::class create Container { 
    constructor {} { 
     puts "Created a [self] that is a Container" 
     InsideThing create inner1 
     InsideThing create inner2 
    } 
    destructor { 
     puts "Deleted a [self] that is a Container" 
    } 
    method echo1 {text} { 
     # how to do something like this: 
     $inner1 echo $text 
    } 
} 

我怎么会去访问这些内置物?我想要做的事情如下:

set c [Container new] 

# (1) accessing inner1 indirectly 
$c echo1 "Hallo World" 

# (2) accessing inner1 dirctly 
$c inner1 echo "Hallo World" 

有没有办法做到这一点?这种做法甚至有意义吗?

我想要实现的是一个嵌套的对象结构(基本上树状)。我希望能够通过调用节点上的方法(例如父节点,子节点)来导航此结构。也破坏了根应该销毁所有的孩子(这就是为什么我用create创建父命名空间内嵌套的对象)

回答

2

要只是普通的使用包含的对象,只是使用它的本地的名字,你应该知道,因为你create它在构造函数中。它不需要被保存在一个变量中;确保它是一个唯一的名称是完全微不足道的,因为它将位于一个唯一的名称空间中(实例名称空间;每个TclOO对象都有它自己的私有名称空间用于这类事情),并且完全控制它。

暴露内部对象最容易使用转发方法完成。 TclOO提供两种主要的用户可配置方法:“正常”proc - 您声明的方法(method)和转发方法(有点像interp alias),您声明的方法是forward。你转发的东西已经解决了实例命名空间,这是 -useful! 特别是,您可以在转发到相关内部对象的容器类上制作forward方法。像这样(InsideThing不变):

oo::class create Container { 
    constructor {} { 
     puts "Created a [self] that is a Container" 
     InsideThing create innerABC 
     InsideThing create innerDEF 
    } 
    destructor { 
     puts "Deleted a [self] that is a Container" 
    } 
    method echo1 {text} { 
     # Just use the name. That's all. 
     innerABC echo $text 
    } 
    forward inner1 innerABC 
    forward inner2 innerDEF 
} 

然后就可以调用到像内部对象:

$c inner1 echo "Yo!" 

或者你可以用这样的中介常用的方法:

$c echo1 "Hiya!" 

随你便。 (在我的非正式测试中,转发版本的速度比您的代码的修改版快了20%左右,但是实际的代码会显着减少差异;微型基准标记实际上很少有用。

+0

非常感谢。我期望它是一些简单的东西,非常有用,知道它是非常有用的;) – PeterE 2014-11-05 16:00:22

+0

对于任何人一起阅读,我在某些地方使用'innerABC'而不是'inner1'来使它更清晰,名称与什么相匹配。就这样… – 2014-11-05 16:19:13