内部構造(Tcl オブジェクト)
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/08/10 13:51 UTC 版)
「Tcl/Tk」の記事における「内部構造(Tcl オブジェクト)」の解説
Tcl パーサーは、スクリプト文字列を受け取り、常に処理結果を文字列で返すように見える。これでは文字列の解析や文字コードとバイナリ値への変換が頻繁に行われていることになり、いかにも効率が悪く思える。しかし決してそのような単純なものではなく、内部では可能な限りバイナリ値を維持している。Tcl スクリプトでバイナリ値も扱えるのはこのおかげである。 例えば下記のように変数に数値を与え、その計算結果を変数に格納するとき、おのおの変数の型は文字列と double の二つの型を持つ。文字列として参照されるときは文字列型として振る舞い、double として参照されるとき(計算式の中などで)は double 型として振る舞うことができる。 set a 100.0 set b 200.0 set c [expr $a * $b] Tcl パーサー内部において変数は Tcl オブジェクトとして存在している。Tcl オブジェクトは char *、int、double の共用体を持った構造体であり、文字列への変換が要求されない限り、int 値は int 値のまま、double 値は double 値のまま維持される。スクリプトでは変数の型宣言を行えないが、変数への値セットで型が仮定され、Tcl オブジェクト間のデータ移動で無駄な型変換が行われないように配慮されている、ということである。 リストも同様に内部ではリスト型の Tcl オブジェクトとして存在している。このような仕組みになっているので、リストを作成する時は list コマンドを用いるべきであることが分かる。また、巨大なリストを文字列として全体参照するのも効率を悪くするので慎重にすべきである。下記の例では変数 listA には文字列として格納されるが、listB には int 値のリストとして格納される。この後、これらの変数にリスト処理コマンドでアクセスすると、listA に対しては要素分解処理が行われるが、listB に対しては不要となる。 set a 100 set b 200 set listA "$a $b" set listB [list $a $b] 前項で解説したコマンド登録関数の後者(Tcl_CreateObjCommand)は、Tcl パーサーからの引数を、無駄に文字列変換することなく、Tcl オブジェクトのままで受け取るコマンド関数を登録するためのものである。 返値も Tcl オブジェクトを通じて返すことができる。下記は long 値をそのまま返す例である。 /* long値を返す例 */ Tcl_SetLongObj (Tcl_GetObjResult (interp), longVal) ; 返値のみならず、Tcl オブジェクトは不要になったとき自動的に削除される仕組みがある。それは Tcl オブジェクトが持つ「参照カウンタ」による制御である。アプリケーションで Tcl オブジェクトを作成し、それを存続したければ参照カウンタを増加させておき(Tcl_IncrRefCount)、必要なしとなったところで減ずる(Tcl_DecrRefCount)ようにする。参照カウンタが減らされて 0 になったときにのみ、そのオブジェクトは削除される。つまり、存続と廃棄の要求を自分だけの都合で出しておくだけで、削除のタイミングがコントロールされるという仕組みである(スマートポインタ)。 変数のみならず、スクリプト自体も Tcl オブジェクトとして存在している。
※この「内部構造(Tcl オブジェクト)」の解説は、「Tcl/Tk」の解説の一部です。
「内部構造(Tcl オブジェクト)」を含む「Tcl/Tk」の記事については、「Tcl/Tk」の概要を参照ください。
「内部構造」の例文・使い方・用例・文例
- 内部構造のページへのリンク