2

これは Tcl 8.4 です。

ユーザーが指定した他の手順に共通することを実行できる手順を作成しようとしています。

例えば:

proc process_menu_item {command args {count 1}} {
    set inf     [expr {$count == -1 ? 1 : 0}]
    set end_str [expr {$count == -1 ? "inf" : $count}]
    set loop_cnt 0

    while {$inf || $count > 0} {
        incr loop_cnt
        puts [format "------- %s -------" [bold "LOOP $loop_cnt of $end_str"]]

        $command $args
    }
    return
}

この手順は、指定された $command を $count 回だけ実行することを望んでいました。私が遭遇する問題は、引数を渡すことです。

次のようなプロシージャを呼び出したいとしましょう。

proc example {{par_a {-1}} {par_b {-1}} {par_c 1}} {
    puts "All params: $par_a $par_b $par_c"
}

どのように電話すればよいprocess_menu_itemですか? それは可能ですか?文字列、リストを試しましたが、最終的par_aにすべての引数の大きなリストを取得します。

ありがとうございました。

4

3 に答える 3

4

(まずargs、プロシージャへのパラメータは、それが最後にある場合にのみ魔法のようになります。その後に何かを配置すると、単なる通常の変数になります。ご存じのとおり、もちろん、ここで必要なものでさえあるかもしれません!)

から呼び出すにはprocess_menu_item、次のように変更します。

$command $args

これに (Tcl 8.4 以前):

eval $command $args

まあ、もしあなたが偏執的であるなら、実際にこれを書いてください:

eval [list $command] [lrange $args 0 end]

または、Tcl 8.5 (またはそれ以降) を使用します。

$command {*}$args

次に、おそらく次のように呼び出し process_menu_item作成します。

process_menu_item frobnicate [list foo bar]

list(多くの Tcl コマンドでリストを作成できます) を使用するか、リテラルを使用するよりも、他の方法がいくつかあります。

process_menu_item frobnicate {foo bar}

推奨されないのは、内部の変数を参照するリテラルに何かを入れることですprocess_menu_item(これは、最短のeval- ベースの形式でのみ機能します)。それは素晴らしいことを可能にしますが、信じられないほど壊れやすいものでもあります。ループ変数を渡したい場合、それはかなり可能ですが、もう少し高度なテクニックが必要です (別の質問をする必要があります)。

于 2012-04-28T07:08:50.857 に答える
2

いつでもラッパー関数を構築できます。

proc wrapper {arg_list} {
    example [lindex $arg_list 0] [lindex $arg_list 1] [lindex $arg_list 2]
}

TCL 8.5 には、このようなことのために設計された{*}演算子があります。

% proc test {a b c} {
    puts a
    puts b
    puts c
}
%
% set inp [list "A" "B" "C"]
A B C
% test $inp
wrong # args: should be "test a b c"
% test {*}$inp
a
b
c
于 2012-04-27T23:00:20.943 に答える
0

現時点では、より包括的な回答を提供することはできinterp aliasませんが、あなたが行きたい場所にたどり着けるかもしれません. rosettacode.orgに例があります。それがうまくいかない場合は、おそらくコマンド トレースを調べてください。これらはすべてのコマンドに対して実行され、コマンド名に基づいて選択できます。

于 2012-04-28T10:57:39.217 に答える