デフォルトでは、Tcl インタープリター内で作成されたプロシージャはグローバル名前空間内に作成されます。この欠点は、異なるソースからの複数の Tcl スクリプトが使用される場合に、プロシージャ名または変数名の競合が発生する可能性があることです。また、一部のプロシージャのみで使用される、ユーザーが直接アクセスすることを意図しないプロシージャが、グローバル名前空間に含まれることになる可能性もあります。
Tcl では、すべての変数およびプロシージャをグローバル名前空間内で定義する代わりに、範囲を制限した変数およびプロシージャを含む名前空間がサポートされています。名前空間はネストさせることができ、範囲のレベル数の制限なしで、名前空間内に別の名前空間を定義できます。名前空間は、プロシージャ名および変数名に新しい構文を追加します。2 つのコロン (::) で、変数名またはプロシージャ名と名前空間名を区切ります。
次の例に、名前空間の作成方法とその名前空間にプロシージャおよび変数を割り当てる方法を示します。この例では、2 つのパブリック プロシージャ (foo
および push
) を含む小さなスタックの機能を再生する名前空間 pop
を作成しています。
01 namespace eval foo {
02 variable stack [list]
03 variable count 0
04 variable params
05 array set params [list var1 value1 var2 value2 var3 value3]
06
07 namespace export push pop
08
09 proc push { args } {
10 variable stack
11 variable count
12 lappend stack $args
13 incr count
14 }
15
16 proc pop {} {
17 variable stack
18 variable count
19 if {[llength $stack] > 0} {
20 set value [lindex $stack end]
21 set stack [lrange $stack 0 end-1]
22 incr count -1
23 return $value
24 } else {
25 error " no more element in the stack"
26 }
27 }
28
29 }
30
31 proc foo::dump {} {
32 variable stack
33 variable count
34 if {[llength $stack] > 0} {
35 puts " There are $count element(s) in the stack:"
36 foreach element $stack {
37 puts " $element"
38 }
39 return 0
40 } else {
41 error " no element in the stack"
42 }
43 }
44
45 namespace import foo::*
説明:
- 次のコマンドを使用して名前空間を定義します。
namespace eval <
name> { … }
- 行 1 は名前空間
foo
を定義し、行 29 は名前空間定義の閉じかっこです。 - 名前空間内の変数は、
variable
コマンドで作成します (行 2 ~ 4)。variable <varname> ?<varvalue>?
Tcl 配列を
variable
コマンドで初期化することはできません。まず作成し (行 4)、その後で初期化する必要があります (行 5)。注記: 名前空間内で変数を定義するのにset
コマンドを使用しないでください。そのようにすると、グローバル名前空間に同じ変数名がある場合に Tcl インタープリターで混同される可能性があります。 - プロシージャは、名前空間定義の中または外に作成できます。コマンド
namespace eval … { … }
内でプロシージャを作成した場合、名前に名前空間の修飾子 (この例ではfoo::
) は必要ありません。行 9 および 16: 名前空間定義内に
push
およびpop
を作成します。 - プロシージャを名前空間定義外で作成し、プロシージャ名に完全な名前空間修飾子を付けて名前空間に追加することもできます。上記の例では、プロシージャ
dump
を名前空間定義外で作成し、名前空間 foo に追加しています (行 31)。 - 行 10~11、17~18、32~33: プロシージャで、キーワード
variable
を使用して名前空間内で作成された変数を参照します。 - 名前空間内で作成されたプロシージャは、完全な名前空間修飾子 (
foo::push
、foo::pop
、foo::dump
など) を使用してアクセスできます。同じ名前空間内のプロシージャを参照する場合は、名前空間修飾子は必要ありません。たとえば、dump
プロシージャでpush
を呼び出す必要がある場合、foo::push
ではなくpush
を指定します。 - 行 7: 名前空間では、パブリックおよびプライベート プロシージャという概念がサポートされます。名前空間内のすべてのプロシージャは完全な名前空間修飾子を使用してアクセスできますが、コマンド
namespace export…
を使用すると、どのプロシージャを名前空間外にエクスポートするかを指定できます。プロシージャ名をエクスポートすると、コマンドnamespace import…
(行 45) を使用してグローバル名前空間にインポートできます。このようにすると、プロシージャを完全な名前空間修飾子を指定せずに直接呼び出すことができるようになります。次に、名前空間
foo
の使用例を示します。vivado% foo::push This is a test 1 vivado% foo::push {This is another line} 2 vivado% push This is the third line 3 vivado% foo::dump There are 3 element(s) in the stack: This is a test {This is another line} This is the third line 0 vivado% puts "The last element stacked is: [foo::pop]" The last element stacked is: This is the third line vivado% puts "The previous element stacked is: [pop]" The previous element stacked is: {This is another line} vivado% foo::dump There are 1 element(s) in the stack: This is a test 0 vivado% dump invalid command name "dump"