2012-02-20 27 views
2

TCLの名前空間に変数に関する質問があります。TCLの名前空間の変数

私は2つの.tclファイル、a.tcl、b.tclを持って、私は例えば、これら2つのファイルに同じグローバル変数を定義します。

a.tcl

variable same "hello1" 

b.tclを

variable same "hello2" 
proc use {} { 
    puts same 
} 

しかしb.tclで、私は「same」変数を使用するには、PROCを定義しようとするが、それは紛争のですか?これはproc use()で使用されていますか?

答えて

4

あなたの疑問そのファイルは名前空間と関係があります。この考えは間違っています。

a.tcl

variable same "hello a" ;# global namespace 

b.tcl

variable same "hello b" ;# global namespace 
proc use {} { 
    variable same ;# reads from the global namespace 
    puts $same ;# will puts "hello a" or "hello b" depending on whether 
        ;# a.tcl is sourced after b.tcl or not 
} 

c.tcl

namespace eval ::not_the_global { 
    variable same "hello c" ;# a different namespace, and a different variable than 
          ;# the one from the previous two files 
} 

d.tcl

namespace eval ::not_the_global { 
    proc use {} {  ;# a different use proc from the one in b.tcl 
     variable same ;# the variable defined in this namespace in c.tcl 
     puts $same ;# will output "hello c" no matter is a.tcl or b.tcl 
         ;# were sourced 
    } 
} 

コードのファイルが名前空間その他のものと無関係であるというストーリーの道徳は、コマンドまたは変数を別の名前空間に入れるには、明示的にそこに配置する必要があります。

3

手順はsame変数と同じ名前空間になります(コードは、コマンドと変数を作成する名前空間と100%直交しています)。 ただし、の本文は、すべてのプロシージャ宣言された変数がデフォルトでローカル変数であるため、useの本文はデフォルトで名前空間の変数にアクセスできません。これはsameへのアクセスを得るために、あなたはおそらく値初期化引数を指定せずに、variableとスコープにそれを持参する必要があることを意味します

proc use {} { 
    variable same 
    puts $same 
} 

ます。また、直接、変数の完全修飾名を使用することができますが、それは傾向がありますより遅くなる(特にループで)。


あなたが尋ねる前に、私はuseがa.tclとb.tclがsource Dである順序によって、「hello1」または「hello2」のいずれかを印刷させるために上記のコードを期待したいです。どんな名前空間もnamespace eval ::someNsName { ...script... }で明示的に行わなければなりません。あなたはおそらく、あなたのスクリプトファイルの残りの内容の周りにそのようなものを置くでしょう。あなたがソースファイルの順序に過度に依存するコードを書くことは、通常、悪い書式とみなされます。ほとんどの場合、デバッグするのはかなり難しい傾向があるためです...

+0

コードは、コマンドと変数を作成する名前空間と100%直交しています)。 "あなたは意味ですか?使用プロシージャはa.tclで同じ変数を見ることができませんか? b.tclのものだけが見えますか? –

+0

@ratzip私は、ファイルと名前空間が、彼らの仕組みにおいて互いに何の関係もないことを意味します。すべての 'source'はファイルの内容を文字列に読み込み、その文字列を' eval'します。 (まあ、 'info script'も設定していますが、細かい点です。)ファイル内に明示的に書かれていなければ、名前空間は使われません。つまり、a.tclとb.tcl _will_は、同じコンテキストからソースを取得した場合、同じ変数を参照します。 –

+0

さらに、異なるコンテキストまたは異なる注文から実行したときのコードの動作が変更されないように、ネームスペースを明示的に指定することをお勧めします。あなたはそれほど簡単ではありませんが、それははるかに簡単です... –

1

すぐに2つのファイルについては忘れてしまいます。

variable x hello ;# this is a global variable. 

proc use {} { 
    puts $x 
} 

これは$xのようなものが定義されていないと言うエラーになる必要があります:あなただけの1つのファイルを持っていると、コンテンツがあると仮定します。どうして?なぜなら、TclはCと異なり、あなたが要求していない関数には何もインポートしないからです。もう一度言ってみましょう:tcl procsには、あなたが見るように言わないグローバル変数または名前空間変数は表示されません。だから、

、伝統的な方法はglobalコマンドを使用することでグローバル変数をインポートするには:

variable x hello 

proc use {} { 
    global x ;# import $x into this proc 
    puts $x 
} 

これは動作するはずですが。 variableコマンドは名前空間の変数を参照する名前空間で定義されprocsのを許可するために作成されましたので、言葉globalは意味がありませんもちろんの名前空間を持つ

namespace eval foo { 
    variable x hello 

    proc use {} { 
    variable x ;# import $x into this proc 
    puts $x 
    } 
} 

グローバルインポートする別の方法もありますし、 globalまたはvariableのいずれかを明示的に使用せずに名前空間変数を使用する場合は、完全な名前空間を指定します。グローバル名前空間はとても以下も動作します単に::次のとおりです。

variable x hello 

proc use {} { 
    puts $::x 
} 

そしてもちろん

:あなたは(どのファイルの使用手順は同じ変数と同じ名前空間になります」によって何を意味するか

namespace eval foo { 
    variable x hello 

    proc use {} { 
    puts $foo::x 
    } 
} 
関連する問題