2014-06-11 20 views
0

我是相當新的TCL,和我想要實現這樣的事情:進口程序訪問Tcl的名字空間變量

namespace eval foo { 
    namespace export bar 
    proc bar {} { 
     puts $bob 
    } 
} 

namespace eval fred { 
    namespace import foo::* 
    variable bob "" 
} 

fred::bar 

然而,我發現,酒吧的範圍內被稱爲foo,所以它告訴我foo :: bob不存在。

我該如何讓fred :: bar訪問fred :: bob?

非常感謝!

+0

你想假裝做OO嗎?如果是這樣,爲什麼不使用_real_對象系統? (如果你使用的是Tcl 8.6,它肯定會有TclOO,並且應該和[incr Tcl]一起出現)我寫了TclOO ...) –

+0

實際上,是的,但我不確定它是否是我正在使用的Tcl 8.6,而且我沒有太多時間在Tcl中學習OO。我也不想偏離一些現有的代碼太遠。最後,我在全局命名空間中定義了我的函數(因爲我不打算在其他命名空間中重新定義它們),並且只傳入命名空間名稱來檢索正確的變量。 – LordSputnik

回答

0

基本問題是你爲什麼要這樣做?

這不是Tcl命名空間通常使用的風格。實際上即使是namespace import也沒那麼用。

這是一個非常脆弱的設計,使得測試更加困難並且隱藏了proc欄的依賴關係。所以嘗試用這種方式來做事可能是不好的風格。

當然你也可以做這樣的事情,但它往往變得怪異,並需要特製的PROC bar,這個工作,但相當難看:

namespace eval foo { 
    namespace export bar 
    proc bar {} { 
     if {[info level 0] eq [namespace origin [info level 0]]} { 
      # called from our native namespace... 
      puts "Oops." 
     } else { 
      set foreign_ns ::[namespace qualifiers [info level 0]] 
      namespace upvar $foreign_ns bob bob 
      puts $bob 
     } 
    } 
} 

namespace eval fred { 
    namespace import ::foo::* 
    variable bob "hello bob" 
} 

fred::bar 

打印「Hello鮑勃」。

所以也許試着解釋一下你真的想在另一個問題中用這種導入來做什麼,並且可能會有更有用的答案。

+0

我意識到這不是一個真正的工作解決方案,但即使作爲一個例子,我認爲最好使用'namespace upvar $ foreign_ns bob bob'而不是'set varname $ {foreign_ns} :: bob',這樣你在問題中可以有'puts $ bob'。 –

+0

是的。 'namespace upvar'將是一個有用的補充。 – schlenk