2

変数値がいつ変更されるかを理解できない場合があります。そして、変数にウォッチポイントを置いて行を見つける必要があります。これはどのように行うことができますか?変数が変更された行を取得するために、TCL トレース コマンドを使用できますか?

4

1 に答える 1

4

変数にウォッチポイントを設定するには、traceコマンドを使用します。infoコマンド、特にlevelおよびサブコマンドを使用して、変数が割り当てられたコンテキストに関する拡張情報を取得できますframe。(後者は Tcl 8.5 以降でのみ利用可能です。)

このようにまとめると、必要な情報が得られるはずです。

trace add variable x write peekLocation
proc peekLocation args {
    puts "WRITTEN FROM >[info level -1]< CALL"
    puts "DETAILS: [info frame -1]"
}
# Demonstration...
proc foobar {} {
    global x  
    set x "jibber jabber"
}
foobar

ただし、うまくいきません。変数が更新されたときにどの手順が実行されていたかを簡単に見つけることができますが、その手順のどこで更新が行われたかはわかりません。(代わりに、トレースコールバック自体の呼び出し、またはスタックのさらに上のレベルで、操作を行うプロシージャへの呼び出しが表示されますが、どちらもそれほど役に立ちません...)


[編集]: 別のアプローチは、どのコマンドが更新を行っているか (例: ) を想定し、 (行番号を提供できる唯一のコマンド) が正しいことを実行できるようにset、少しジガリーポーキーを行うことです:info level

rename set __orig_set;proc set args {doTrace;uplevel 1 [list __orig_set {*}$args]}
# Separate the probe from the instrumentation
proc doTrace {} {
    puts [info frame -2]
}

それはうまくいきます。変数の設定を行う他のコマンド ([incr]、[lappend]、[lset] など) に拡張することもかなり簡単です。より洗練されたプローブは次のとおりです。

proc doTrace {} {
    __orig_set f [info frame -2]
    dict with f {
        switch $type {
            source {
                puts "Write happened on line $line of file $file"
            }
            proc {
                puts "Write happened on line $line of procedure $proc"
            }
            default {
                puts "Write happened on line $line (command was >$cmd<)"
            }
        }
    }
}

気軽に実験してください!

于 2011-04-24T16:05:24.987 に答える