0

以下に示すように、次の関数またはプロシージャのデカルレーションがあります。ここでは、proc 名自体が別の場所からの名前空間であり、別のファイルを意味します。その名前空間がどこから来たのか、どのファイルから来たのかを知るにはどうすればよいですか?

例:

proc ::a::b {some argument} {
    body
}

上記の例では、 ::a::b の名前空間「a」がどこから来ているか、使用されているかを明示的に知りたいです。それは同じファイルではなく、同じディレクトリに100個ほどの他のファイルがあります。

名前空間のコードと名前空間の起点を使用してみましたが、どちらも機能しませんでした。

4

3 に答える 3

2

ソースコード全体を検索したくない場合 (実際のプロシージャ名は簡単ですが、 b! のような短い例を使用する場合はそうではありません)、何が定義されているかを検出することで、定義されている場所に関する情報を構築できますprocは通常のコマンドであるため、これprocはすべて機能します。

proc追跡を追加するためのオーバーロード

これを行う古典的な方法は、名前を変更procして追跡コマンド (手順) をその場所に配置し、procそれが完了すると名前が変更された元のコマンドに委譲することです。

rename proc _real_proc
_real_proc proc {name arguments body} {
    global definitionLocations
    if {![string match "::*" $name]} {
        set name ::[string trimleft [uplevel 1 {namespace current}]::$name ":"]
    }
    set definitionLocations($name) [file normalize [info script]]
    uplevel 1 [list _real_proc $name $arguments $body]
}

そのコードを他のアプリケーション コードの前に置くと、各プロシージャがグローバル配列sourceのどこで定義されているかを正確に追跡します。definitionLocations

トレース付きの追跡を添付する

この監視コードをアタッチするもう 1 つの方法は、実行トレースを使用することです。

trace add execution proc enter {apply {{arguments op} {
    global definitionLocations
    set name [lindex $arguments 1]
    if {![string match "::*" $name]} {
        set name ::[string trimleft [uplevel 1 {namespace current}]::$name ":"]
    }
    set definitionLocations($name) [file normalize [info script]]
}}}

これがオーバーライドよりもきちんとしているかどうかはわかりprocません (正直に言うと、痕跡は少し怖いです)。

ただし、問題の手順を定義する前に追跡を添付する必要があるという点は依然として当てはまります。

于 2013-08-02T08:33:32.710 に答える
0

名前空間が存在するファイルを探している場合は、Tcl Dev Kit Cross Reference Tool (XRef ) を参照してください
。XRef ツールは Tcl ソース コードをスキャンし、Tcl コード コンポーネント間の関係を示す相互参照データベースを構築します。 . これらのコンポーネントには、パッケージ、ファイル、名前空間、コマンド、および変数が含まれます。各 Tcl コンポーネントは、コードが定義、宣言、使用、配置されている場所を表示するために展開できるツリー階層で表示されます。

他にも相互参照ツールがいくつかあります。

于 2013-08-02T04:11:27.683 に答える