2012-04-03 20 views
1

Tcl 8.4。名前空間名に変数tclを使用する

私はこのnamespace木があります。

namespace eval menu_tree { 

    #-------------------------------------------------------------------------- 
    ## Main Menu 
    namespace eval main_menu { 
     variable title "Main Menu" 
    } 

    #-------------------------------------------------------------------------- 
    ## Setup Menu 
    namespace eval setup_menu { 
     variable title "Show Setup Information" 
    } 

    #-------------------------------------------------------------------------- 
    ## Help Menu 
    namespace eval help_menu { 
     variable title "Show Help Information" 
    } 
} 

のアイデアは、このような機能を持っていることでした。

proc print_title {menu} { 
    puts $menu::title 
} 

これはグローバル変数と正常に動作します。しかし、私が見つけることができるから、名前空間名に '$'を使うことが必要です。私はウェブ上で答えを見つけようとしましたが、何も出てこなかった。 誰でもそれを行う方法を知っていますか、それが可能であれば?

ありがとう、 -Ilya。

答えて

4

ここでの重要なアプローチは、「元のTcl」には「$」構文砂糖がまったくないことに留意することです。変数の内容を取得するオリジナルの方法はsetに1引数の呼び出しです:

したがって
set foo bar ;# sets variable "foo" to contain the value "bar" 
puts [set foo] ;# prints the value contained in variabe "foo" 

${menu}::titleが名前に展開されるように、あなたはおそらく

proc print_title {menu} { 
    puts [set ${menu}::title] 
} 

のようなものを使用する必要があります変数の値を取得すると、setはその変数の値を取得します。

"menu"という言葉のまわりの中括弧の使い方に注意してください。Tclはそれがなければ、おそらくあなたが意図したものではない "menu :: title"という名前の変数を逆参照しようとします。

もう1つのことは、print_titleの動作が「メニュー」引数の内容に大きく依存していることです。拡張後、setコマンドは解決できる文字列を参照する必要があります。 a set of rules。より詳細な情報がわかるまで、アドバイスを受けるのは難しいです。

詳細については、this questionを参照してください。$setトピック。

+0

「$ {menu}」がトリックでした。 'puts [set menu_tree :: $ {menu} :: title]' – ilya1725

+1

同じ変数を1つのプロシージャで2回操作しているなら、エイリアスに 'upvar'を使う方が簡単になるでしょうそれをローカル変数名に変換します。 'upvar menu_tree :: $ {menu} ::タイトルフルーツバス。 puts $ fruitbat' –