ソースコード全体を検索したくない場合 (実際のプロシージャ名は簡単ですが、 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
ません (正直に言うと、痕跡は少し怖いです)。
ただし、問題の手順を定義する前に追跡を添付する必要があるという点は依然として当てはまります。