1

エクスポートする名前空間「b」で定義されたいくつかの関数があります。次に、これらの関数を名前空間 ::x::Y にインポートします。したがって、次のようになります。

namespace eval ::x::y "namespace import fun"

しばらくして、私は次のことを行います:

namespace eval ::x::y fun

楽しい場所:

proc fun {} {
   puts "[namespace current]"
   uplevel {puts "[namespace current]"}
}

印刷されるものは次のとおりです。

::b
::x::y

私が望んで必要としているのは、::b ではなく ::x::y で「楽しみ」が発生することです。私は何を間違っていますか?

4

1 に答える 1

1

それは、Tcl の名前空間がどのように機能するかではありません。各プロシージャは、その名前が配置されている 1 つのネームスペースに正確に関連付けられています。を使用するnamespace importと、プロシージャのエイリアスがインポート中の名前空間に配置され、他の名前空間からプロシージャを呼び出すことができますが、プロシージャ自体は元の名前空間に残り、その名前空間で実行されます。

呼び出し元の名前空間を知りたい場合は、を使用しますuplevel namespace current(またはuplevel 1 {namespace current}、少し風の強いがより効率的なバージョンを使用します)。ただし、これは実際には、プロシージャを呼び出すために使用されたコマンドがどの名前空間に含まれているかを示しているわけではありません。そのためには、この怪物が必要です(呼び出されたコマンドで):

namespace qualifiers [uplevel 1 [list namespace which [lindex [info level 0] 0]]]

もちろん、それがたくさん必要な場合は、おそらく何か間違ったことをしているでしょう。(情報を取得するために必要なコードの長さと複雑さを考えると、これは明らかです。)

特に、これでオブジェクト指向を行うふりをしている場合は、停止して、トリッキーな詳細をすべて正しく取得する実際のオブジェクト システムを使用してください。Tcl 8.6.0 には1 つ(提供された拡張機能がある場合は 2 つ) が含まれており、拡張パッケージとして利用可能な古いバージョン用のものが多数あります

于 2012-12-27T10:27:13.623 に答える