## Tcl8.6.17/Tk8.6.17 Documentation > Tcl C API > Object

### Tcl/Tk Applications | Tcl Commands | Tk Commands | [incr Tcl] Package Commands | SQLite3 Package Commands | TDBC Package Commands | tdbc::mysql Package Commands | tdbc::odbc Package Commands | tdbc::postgres Package Commands | tdbc::sqlite3 Package Commands | Thread Package Commands | Tcl C API | Tk C API | [incr Tcl] Package C API | TDBC Package C API

  NAME
    Tcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared, Tcl_InvalidateStringRep — Tcl 値を操作する　　manipulate Tcl values
  SYNOPSIS
    #include <tcl.h>
    Tcl_Obj *
    Tcl_NewObj()
    Tcl_Obj *
    Tcl_DuplicateObj(objPtr)
    Tcl_IncrRefCount(objPtr)
    Tcl_DecrRefCount(objPtr)
    int
    Tcl_IsShared(objPtr)
    Tcl_InvalidateStringRep(objPtr)
  引数 ARGUMENTS
    Tcl_Obj *objPtr (入力in)
  緒論 INTRODUCTION
  THE TCL_OBJ STRUCTURE
  値の寿命の例 EXAMPLE OF THE LIFETIME OF A VALUE
  値の保存管理 　STORAGE MANAGEMENT OF VALUES
  SEE ALSO
  KEYWORDS

### NAME

Tcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared, Tcl_InvalidateStringRep — Tcl 値を操作する　　manipulate Tcl values

### SYNOPSIS

#include <tcl.h>
Tcl_Obj *
Tcl_NewObj()
Tcl_Obj *
Tcl_DuplicateObj(objPtr)
Tcl_IncrRefCount(objPtr)
Tcl_DecrRefCount(objPtr)
int
Tcl_IsShared(objPtr)
Tcl_InvalidateStringRep(objPtr)

### 引数 ARGUMENTS

Tcl_Obj *objPtr (入力in)
  値を指す; 事前に Tcl_NewObj を呼出した結果でなければならぬ｡　 Points to a value; must have been the result of a previous call to Tcl_NewObj.

### 緒論 INTRODUCTION

この取扱説明書の頁は Tcl 値(歴史的理由で Tcl_Obj と呼ばれる)の全貌と､それが如何に使われるかを提示する｡又 Tcl 値を管理する一般的手続を記述する｡これらの手続は値の生成と複写､及び､値の参照(ポインター)の計数の増加と減少に使われる｡手続函数は Tcl_GetIntFromObj や Tcl_ListObjAppendElement の様に特定の値の型の操作をするものと一緒に使われる｡個別の手続函数はそれが操作するデータ構造に従って記述されている｡　　　　 This man page presents an overview of Tcl values (called Tcl_Objs for historical reasons) and how they are used. It also describes generic procedures for managing Tcl values. These procedures are used to create and copy values, and increment and decrement the count of references (pointers) to values. The procedures are used in conjunction with ones that operate on specific types of values such as Tcl_GetIntFromObj and Tcl_ListObjAppendElement. The individual procedures are described along with the data structures they manipulate.

Tcl の２門値は Tcl 値の保存と交換の為の一般目的の仕組みを提供する｡それらは大いに Tcl 内の文字列の慣行を置換える｡譬えば､それらは､変数値､命令引数､命令の結果､記述譜を保存する為に使われる｡ Tcl 値は文字列の様に振舞うが､より効率的に操作可能な内部表現をも保有する｡譬えば､ Tcl リストは今や､リストの文字列表現を保有する値ばかりでなく､それぞれのリスト要素についての値へのポインターの配列をも同じく代表する｡二門値は大部分の実行時型変換を回避する｡それらは適切な表現が直ぐに利用できるので多くの記憶の操作の速度を向上する｡機械語翻訳自身は Tcl 値を機械語翻訳する記述譜からの機械的バイト符号結果を高速記憶する｡　 Tcl's dual-ported values provide a general-purpose mechanism for storing and exchanging Tcl values. They largely replace the use of strings in Tcl. For example, they are used to store variable values, command arguments, command results, and scripts. Tcl values behave like strings but also hold an internal representation that can be manipulated more efficiently. For example, a Tcl list is now represented as a value that holds the list's string representation as well as an array of pointers to the values for each list element. Dual-ported values avoid most runtime type conversions. They also improve the speed of many operations since an appropriate representation is immediately available. The compiler itself uses Tcl values to cache the instruction bytecodes resulting from compiling scripts.

二つの表現は相互に高速域に記憶され､遅延的に計算される｡即ち､それぞれの表現は必要なときに限り算出される､他方から算出され､一度計算されると保存される｡更に､片方の表現の変化は他方を無効にする｡譬えば､整数計算の Tcl 算譜は整数と文字列の間の絶えざる変換なしに変数の内部装置整数表現で直接操作できる｡変数の値の文字列表現が必要な時にのみ､譬えばそれの印刷､算譜は整数から文字列表現を再発生する｡値が内部表現を含んでいても､その意味論は文字列の用語に定義される: 最新の文字列は常に得られる､又値の文字列の表現が取出された時､値のどの変更もその文字列に反映される｡この表現の無効化と再発行の理由で､拡張機能著者にとって Tcl_Obj 欄を直接利用することは危険である｡ Tcl_Obj 情報を利用するには Tcl_GetStringFromObj や Tcl_GetString の様な手続函数を使用することが好ましい｡ 　　　　 The two representations are a cache of each other and are computed lazily. That is, each representation is only computed when necessary, it is computed from the other representation, and, once computed, it is saved. In addition, a change in one representation invalidates the other one. As an example, a Tcl program doing integer calculations can operate directly on a variable's internal machine integer representation without having to constantly convert between integers and strings. Only when it needs a string representing the variable's value, say to print it, will the program regenerate the string representation from the integer. Although values contain an internal representation, their semantics are defined in terms of strings: an up-to-date string can always be obtained, and any change to the value will be reflected in that string when the value's string representation is fetched. Because of this representation invalidation and regeneration, it is dangerous for extension writers to access Tcl_Obj fields directly. It is better to access Tcl_Obj information using procedures like Tcl_GetStringFromObj and Tcl_GetString.

値は記述域に割当られ Tcl_Obj 構造へのポインターを使用して参照される｡値は可能な限り共有される｡これは本質的に要求される記憶域を減らす､理由はある値､長いリスト等は非常に大きい為である｡又大部分の Tcl 値は単に読込まれ修正されることはない｡之は特に手続函数の引数でそうなる､それは呼出し側と呼出された手続函数の間で共有される｡代入と引数の束縛は単に値へのポインターの代入によって行われる｡参照の計数は値の記憶を取り戻すことがいつ安全か決めるために使用される｡ 　　 Values are allocated on the heap and are referenced using a pointer to their Tcl_Obj structure. Values are shared as much as possible. This significantly reduces storage requirements because some values such as long lists are very large. Also, most Tcl values are only read and never modified. This is especially true for procedure arguments, which can be shared between the caller and the called procedure. Assignment and argument binding is done by simply assigning a pointer to the value. Reference counting is used to determine when it is safe to reclaim a value's storage.

Tcl の値は型が付けられる｡値の内部表現はその型によって制御される｡ Tcl 中核内に､整数､倍､リスト､バイト符号命令を含む､幾つかの型が予備定義されている｡拡張機能の著者は自身の Tcl_ObjType 構造を定義することにより型を拡張できる｡ Tcl values are typed. A value's internal representation is controlled by its type. Several types are predefined in the Tcl core including integer, double, list, and bytecode. Extension writers can extend the set of types by defining their own Tcl_ObjType structs.

### THE TCL_OBJ STRUCTURE

それぞれの Tcl 値は Tcl_Obj 構造によって表現でき､それは次の様に定義される｡ 　　 Each Tcl value is represented by a Tcl_Obj structure which is defined as follows.

    typedef struct Tcl_Obj {
        int refCount;
        char *bytes;
        int length;
        const Tcl_ObjType *typePtr;
        union {
            long longValue;
            double doubleValue;
            void *otherValuePtr;
            Tcl_WideInt wideValue;
            struct {
                void *ptr1;
                void *ptr2;
            } twoPtrValue;
            struct {
                void *ptr;
                unsigned long value;
            } ptrAndLongRep;
        } internalRep;
    } Tcl_Obj;

bytes と length 要員は一緒に値の UTF-8 文字列表現を保有する､それは零を含まない勘定文字列である(UTF-8 零文字は192, 128の２バイト並びで符号化すべきである(訳注 utf冗長コードでヌルは 0xC0 0x80 ))bytes は文字列表現の最初のバイトを指す｡length 要員はバイトの個数を与える｡バイト配列は常に最後のデータバイトの後に零バイトを有さなくてはならない､length の偏寄位置に; これにより文字列表現は伝統的な零終端 C 文字列として扱われることが可能になる｡C 算譜は値の文字列表現を得る為に Tcl_GetStringFromObj と Tcl_GetString を使う｡もしバイトbytesがNULLの場合､文字列表現は不適正である｡　　　 The bytes and the length members together hold a value's UTF-8 string representation, which is a counted string not containing null bytes (UTF-8 null characters should be encoded as a two byte sequence: 192, 128.) bytes points to the first byte of the string representation. The length member gives the number of bytes. The byte array must always have a null byte after the last data byte, at offset length; this allows string representations to be treated as conventional null-terminated C strings. C programs use Tcl_GetStringFromObj and Tcl_GetString to get a value's string representation. If bytes is NULL, the string representation is invalid.

値の型は内部表現を管理する｡ typePtr 要員は､型を記述している typePtr 構造をす｡もし typePtr が NULL, の場合､内部表現は不適正である｡ 　　　 A value's type manages its internal representation. The member typePtr points to the Tcl_ObjType structure that describes the type. If typePtr is NULL, the internal representation is invalid.

internalRep 団結要員は値の内部表現を保有する｡これは(長精度)整数か､倍精度浮動小数数か､値を表現する為の値の型により必要とされる追加情報を含む値へのポインターか､Tcl_WideInt 整数か､二つの任意のポインターか､符号なし長精度整数とポインターで作られる対か､のどれかである｡　　　 The internalRep union member holds a value's internal representation. This is either a (long) integer, a double-precision floating-point number, a pointer to a value containing additional information needed by the value's type to represent the value, a Tcl_WideInt integer, two arbitrary pointers, or a pair made up of an unsigned long integer and a pointer.

refCount 要員は値の記憶域を解放する為に何時が安全かを伝えるために使われる｡それは値への活動中の計数を保有する｡正しい参照計数の維持は拡張機能著者の鍵となる責務である｡参照計数は下の STORAGE MANAGEMENT OF VALUESの節で論議する｡ 　　　 The refCount member is used to tell when it is safe to free a value's storage. It holds the count of active references to the value. Maintaining the correct reference count is a key responsibility of extension writers. Reference counting is discussed below in the section STORAGE MANAGEMENT OF VALUES.

拡張機能著者は直接 Tcl_Obj 構造の要員を利用できるが､それでも適切な手続函数とマクロを使うことが好ましい｡譬えば､拡張機能著者は refCount を直接読んだり更新してはならない; Tcl_IncrRefCount や Tcl_IsShared の様なマクロを使うべきである｡ 　　　 Although extension writers can directly access the members of a Tcl_Obj structure, it is much better to use the appropriate procedures and macros. For example, extension writers should never read or update refCount directly; they should use macros such as Tcl_IncrRefCount and Tcl_IsShared instead.

Tcl の値の鍵の特性は二つの表現を保有する｡値は典型的には一つの文字列表現のみを有することを始める: それは型は付けられず､ NULLの typePtr を有する｡空文字列を含む値又は指定された文字列の複写は､それぞれ Tcl_NewObj か Tcl_NewStringObj を使って作成される｡値の文字列値は Tcl_GetStringFromObj か Tcl_GetString を使って得られ､ Tcl_SetStringObj を使って変更される｡もし値が後に特定の内部表現を要求する Tcl_GetIntFromObj の様な手続函数に渡されると手続函数はそれを作り値の typePtr を設定する｡その内部表現は｡文字列表現から算出される｡値の二つの内部表現はそれぞれ二元的である: 片方になされた変更は他方に反映される｡譬えば､ Tcl_ListObjReplace は値の内部表現を修正し､次の Tcl_GetStringFromObj や Tcl_GetString への呼出しでその変更を反映する｡ 　　　 A key property of Tcl values is that they hold two representations. A value typically starts out containing only a string representation: it is untyped and has a NULL typePtr. A value containing an empty string or a copy of a specified string is created using Tcl_NewObj or Tcl_NewStringObj respectively. A value's string value is gotten with Tcl_GetStringFromObj or Tcl_GetString and changed with Tcl_SetStringObj. If the value is later passed to a procedure like Tcl_GetIntFromObj that requires a specific internal representation, the procedure will create one and set the value's typePtr. The internal representation is computed from the string representation. A value's two representations are duals of each other: changes made to one are reflected in the other. For example, Tcl_ListObjReplace will modify a value's internal representation and the next call to Tcl_GetStringFromObj or Tcl_GetString will reflect that change.

表現は効率の為に遅延再計算される｡ Tcl_ListObjReplace の様な手続函数による片方の表現は他方の再表現には直ちに反映されない｡その代りに､他方の表現には無効の印が付けられ､後に必要である場合のみ再生成される｡大部分の C 算譜は之が如何になされるかを考慮しない､単純に Tcl_GetBooleanFromObj か Tcl_ListObjIndex の様な手続函数を使ってなされる｡自己の値の型を実装する算譜著者は不適な表現について確認しなければならず､必要な場合には無効の印を附けなければならない｡手続函数 Tcl_InvalidateStringRep は値の文字列表現に不適の印を付けることと､古い文字列表現に結びついたどの領域も解放する為に使われる｡ 　　　　 Representations are recomputed lazily for efficiency. A change to one representation made by a procedure such as Tcl_ListObjReplace is not reflected immediately in the other representation. Instead, the other representation is marked invalid so that it is only regenerated if it is needed later. Most C programmers never have to be concerned with how this is done and simply use procedures such as Tcl_GetBooleanFromObj or Tcl_ListObjIndex. Programmers that implement their own value types must check for invalid representations and mark representations invalid when necessary. The procedure Tcl_InvalidateStringRep is used to mark a value's string representation invalid and to free any storage associated with the old string representation.

値は通常は一つの型が寿命全体に亙って残るが､時には値は別の型に変換を要す｡譬えば､ C 算譜は文字列を Tcl_AppendToObj への繰返し呼出しによって作り上げ､リスト要素の抽出の為に Tcl_ListObjIndex を呼出す｡同じ文字列値を保持する同じ値は、異なる時にいくつかの異なる内部表現を持つことができる｡拡張機能著者は Tcl_ConvertToType 手続函数を使って一つの型から他の型に強制的に値を変換できる｡新しい値の型を作る算譜著者だけが之が如何になされるかを知る必要がある｡値の型の実装の一部として定義された手続函数は新しい値の新しい内部表現を作成しその typePtr を変更する｡如何に新しい値の型を作るかは取扱説明書の頁の Tcl_RegisterObjType を参照されたい｡ 　 Values usually remain one type over their life, but occasionally a value must be converted from one type to another. For example, a C program might build up a string in a value with repeated calls to Tcl_AppendToObj, and then call Tcl_ListObjIndex to extract a list element from the value. The same value holding the same string value can have several different internal representations at different times. Extension writers can also force a value to be converted from one type to another using the Tcl_ConvertToType procedure. Only programmers that create new value types need to be concerned about how this is done. A procedure defined as part of the value type's implementation creates a new internal representation for a value and changes its typePtr. See the man page for Tcl_RegisterObjType to see how to create a new value type.

### 値の寿命の例 EXAMPLE OF THE LIFETIME OF A VALUE

値の寿命の例として､次の命令の並びを考察しよう: As an example of the lifetime of a value, consider the following sequence of commands:

    set x 123

これは型なしの x に値を代入する､その bytes 要員は 123 を指し､ length 要員は 3 を含む｡値の typePtr 要員は NULL である｡ 　　 This assigns to x an untyped value whose bytes member points to 123 and length member contains 3. The value's typePtr member is NULL.

    puts "x is $x"

x の文字列表現は適正( bytes が非-NULLだから)であり､次に､命令に捕捉される｡ x's string representation is valid (since bytes is non-NULL) and is fetched for the command.

    incr x

incr 命令は Tcl_GetIntFromObj を呼出して x の値から最初に整数を得る｡この手続函数は値が既に整数値であるかを確認する｡それが否であるので､値の内部表現を整数 123 に設定して値を変換し､整数 Tcl_ObjType 構造を指す 値のtypePtr を設定する｡両方の表現は今は適正である｡ incr は値の整数内部表現を増加し､その文字列表現を無効にする( Tcl_InvalidateStringRep 呼出しによる)理由は文字列表現は最早内部表現に対応しないから｡ 　　　 The incr command first gets an integer from x's value by calling Tcl_GetIntFromObj. This procedure checks whether the value is already an integer value. Since it is not, it converts the value by setting the value's internal representation to the integer 123 and setting the value's typePtr to point to the integer Tcl_ObjType structure. Both representations are now valid. incr increments the value's integer internal representation then invalidates its string representation (by calling Tcl_InvalidateStringRep) since the string representation no longer corresponds to the internal representation.

    puts "x is now $x"

x の値の文字列表現が必要であり再計算される｡文字列表現は今や 124 であり､両方の表現が適正である｡ The string representation of x's value is needed and is recomputed. The string representation is now 124 and both representations are again valid.

### 値の保存管理 　STORAGE MANAGEMENT OF VALUES

Tcl 値は記述域に割当てされ可能な限り共有され要求される記憶域を減少する｡参照計数は何時値が最早必要でないかを定め安全に解放できる為に使われる｡ Tcl_NewObj か Tcl_NewStringObj に作成された値は参照計数 0 を有する｡マクロ Tcl_IncrRefCount は値への新しい参照が作成された時に参照計数を増加する｡マクロ Tcl_DecrRefCount は参照が最早必要でない時に参照計数を減少し､もし値の参照が零に落ちたときその記憶域を解放する｡異なる符号命令やデータ構造に共有された値は 1 より大きい refCount を有する｡値の参照計数の増加は､不用意に解放されず､又､その値が偶発的に変更されないことを確実にする｡ 　　　 Tcl values are allocated on the heap and are shared as much as possible to reduce storage requirements. Reference counting is used to determine when a value is no longer needed and can safely be freed. A value just created by Tcl_NewObj or Tcl_NewStringObj has refCount 0. The macro Tcl_IncrRefCount increments the reference count when a new reference to the value is created. The macro Tcl_DecrRefCount decrements the count when a reference is no longer needed and, if the value's reference count drops to zero, frees its storage. A value shared by different code or data structures has refCount greater than 1. Incrementing a value's reference count ensures that it will not be freed too early or have its value change accidentally.

実施例の様にバイト符号命令解釈実行機能は引数値を Tcl 呼出し側と被呼び側の間で共有し､複写値の保有を回避している｡それは呼出しの引数値を手続函数の公式の假引数に代入する｡それを行い､今やそれへの公式假引数からの新しい参照があるので､それぞれの引数の参照計数を増加する為に Tcl_IncrRefCountR を呼出す｡呼出された手続函数が制御を返した時､解釈実行機能はそれぞれの引数の参照計数を減らす為に Tcl_DecrRefCount を呼ぶ｡値の参照計数が零以下に落ちた時､ Tcl_DecrRefCount はその記憶域を矯正する｡大部分の命令手続函数は参照計数に就いて考慮をしない､理由は値の値を直ぐさま使い､それを返した後はポインターを保有しないから｡しかし､もしデータ構造内に値へのポインターを保有する場合は､そのポインターは新しい参照なので参照計数を増加する必要がある｡ 　　　　 As an example, the bytecode interpreter shares argument values between calling and called Tcl procedures to avoid having to copy values. It assigns the call's argument values to the procedure's formal parameter variables. In doing so, it calls Tcl_IncrRefCount to increment the reference count of each argument since there is now a new reference to it from the formal parameter. When the called procedure returns, the interpreter calls Tcl_DecrRefCount to decrement each argument's reference count. When a value's reference count drops less than or equal to zero, Tcl_DecrRefCount reclaims its storage. Most command procedures do not have to be concerned about reference counting since they use a value's value immediately and do not retain a pointer to the value after they return. However, if they do retain a pointer to a value in a data structure, they must be careful to increment its reference count since the retained pointer is a new reference.

直接値を修正する lappend や linsert の様な命令手続函数は共有された値を変更する前には註意深く複写しなければならない｡それらは初めに Tcl_IsShared を呼出して値が共有されてないかを確認しなければならない｡もし値が共有されている場合､ Tcl_DuplicateObj を使用して複写しなければならない; これは元の値の新しい複製を返す､それは参照数 refCount 0 を有す｡もし値が共有されていない場合､命令手続函数は値を “所有し” ､安全に直接修正できる｡譬えば､次の命令符号が linsert を実装する命令手続函数に現れる｡この手続函数は index の前の新しい要素に objc-3 を挿入して objv[1] に渡したリスト値を修正する｡ 　　　 Command procedures that directly modify values such as those for lappend and linsert must be careful to copy a shared value before changing it. They must first check whether the value is shared by calling Tcl_IsShared. If the value is shared they must copy the value by using Tcl_DuplicateObj; this returns a new duplicate of the original value that has refCount 0. If the value is not shared, the command procedure “owns” the value and can safely modify it directly. For example, the following code appears in the command procedure that implements linsert. This procedure modifies the list value passed to it in objv[1] by inserting objc-3 new elements before index.

    listPtr = objv[1];
    if (Tcl_IsShared(listPtr)) {
        listPtr = Tcl_DuplicateObj(listPtr);
    }
    result = Tcl_ListObjReplace(interp, listPtr, index, 0,
            (objc-3), &(objv[3]));

他の用例として､ incr の命令手続函数は内部で表現の整数を増加する前に変数の値が共有されているかを確認しなければならない｡もし共有されている場合､他のデータ構造内の偶発的な変更を避けるために値を複製する必要がある｡ 　　　　 As another example, incr's command procedure must check whether the variable's value is shared before incrementing the integer in its internal representation. If it is shared, it needs to duplicate the value in order to avoid accidentally changing values in other data structures.

### SEE ALSO

Tcl_ConvertToType, Tcl_GetIntFromObj, Tcl_ListObjAppendElement, Tcl_ListObjIndex, Tcl_ListObjReplace, Tcl_RegisterObjType

### KEYWORDS

internal representation, value, value creation, value type, reference counting, string representation, type conversion
Copyright © 1996-1997 Sun Microsystems, Inc.