2014-11-05 255 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