0

次のように使用できる関数を書きたいと思います。

my_function {
    cmdA argA_1 argA_2
    cmdB argB_1 argB_2
    cmdC argC_1 argC_2
}

おそらくループで、を使用して my_function を実装したいと思いnamespace eval ::my_internal_namespace [uplevel ...]ます。これはすぐにはあまり役に立ちませんが、後で機能を拡張して、単にuplevel.

my_internal_namespace次のように定義されます。

namespace eval my_internal_namespace {
  proc cmdA { args } {
      puts "$args"
  }

  proc cmdB { args } {
      puts "$args"
  }

  proc cmdC { args } {
      puts "$args"
  }
}

この手法により、最終的に my_function の呼び出し元は、my_function から必要ないくつかの事実と動作を宣言できるようになると思います。これらの事実と動作のパラメーターは、呼び出し元のコンテキストで評価されます。たとえば、変数の値を取得します。または、呼び出し元の名前空間とスコープで他の置換を実行します。

4

1 に答える 1

1

namespace eval単語を直接渡さないのはなぜですか?これは、コマンドのような状況で Tcl が行うことのほとんどです。oo::defineスクリプトとして評価することは、信頼できるコードを解析する驚くほど簡単な方法です。

namespace eval ::my_internal_namespace $the_user_word

信頼できないコードについては、安全なインタープリターをお勧めします。これらの「小さな言語」のアプローチでは、基本的な安全なインタープリターを作成し、公開したくない残りのコマンドを非表示にし、使用可能にするすべてのコマンドのエイリアスを追加するのが最善です。

set i [interp create -safe]
foreach cmd [$i eval {info commands}] {
    $i hide $cmd
}
foreach cmd {cmdA cmdB cmdC} {
    $i alias $cmd ::my_internal_namespace::$cmd
}
$i eval $the_user_word

namespace evalこれは、 ;を実行するだけではかなりコストがかかります。コードが比較的信頼できるものであれば気にしません。

于 2013-02-09T11:13:49.907 に答える