0

これは不可能かもしれませんが、tcl で正規表現を渡す方法はありますか。何かを見つけて比較し、それらが等しいかどうかを確認する場合、文字列に渡すものを変更できないというこの関数があります。

proc check {a } {
    // find b in the database
    if {$a == $b} {
        puts "equals"
    } {
        puts "Not equals"
    }   
 }

問題は、関数が「==」を使用していることです。これは正確な場合にのみ一致しますが、「a」と「b」が同じ単語で始まる場合に「a」と「b」が等しくなるように、「a」にワイルドカードを含める必要があります。

4

2 に答える 2

3

私は変更できないこの機能を持っています

なんで?Tclでは、次のように簡単に再定義できます

proc check {a } {
    # find b in the database
    if {[string match -nocase $a $b]} {
        puts "equals"
    } {
        puts "Not equals"
    }   
}

または、推奨されませんが、 を再定義することもできますif

if実行時に行を検索して置き換えることもできます

proc check [info args check] [string map {
    {if {$a == $b}} {if {[string match -nocase $a $b]}}
} [info body check]]

だから:なぜ機能を変更できないのですか?

于 2013-03-15T14:36:45.227 に答える
1

オペレーターの動作==は固定されています。常に等価性テストを行います。実際、数値の等価性を優先する等価性テストを実行し、他に方法がない場合にのみ文字列の等価性にフォールバックします。

したがって、checkあなたの行動を変えるには、本当にトリッキーになる必要があります。


実行トレースを使用して内部の何かを傍受checkし、ローカル変数に読み取りトレースを配置して、aそれを読み取ったときに、その値が複雑なルールに従って何かと一致するかどうかを実際に取得できるようにすることを検討します。(bおそらく1ブール値の true を保持できます。) これを行うためのコードは非常に複雑であり、私は実際にそれを避けるようにしています!

proc可能であれば、本体にプレフィックスを付けてcheckそこにトレースを適用できるように再定義する方がはるかに簡単です。または、テスト自体をマッサージすることもできます。

# Rename the command to something that nothing else knows about (tricky!)
rename proc my_real_proc

my_real_proc proc {name arguments body} {
    # Replace a simple equality with a basic no-case pattern match
    if {$name eq "check"} {
        set body [string map {{$a == $b} {[string match -nocase $b $a]}} $body]
    }
    # Delegate to the original definition of [proc] for everything else
    uplevel my_real_proc $name $arguments $body
}

の定義の前にそのコードを実行する限り、check(「コードを変更する」ことなく) コードを変更し、必要な種類の機能を取得できます。

于 2013-03-15T15:18:39.720 に答える