Caché オブジェクト
この章では、Caché のオブジェクトについて説明します。以下のトピックについて説明します。
Caché オブジェクト・クラスの概要
Caché は、%Library.RegisteredObjectOpens in a new tab、%Library.PersistentOpens in a new tab、および %Library.SerialObjectOpens in a new tab のオブジェクト・クラスを使用してオブジェクト・テクノロジを提供します。
以下の図は、これらのクラス間の継承関係、およびそれらのパラメータとメソッドのいくつかを示しています。%Library パッケージのクラスの名前は省略可能です。したがって、例えば、%PersistentOpens in a new tab は %Library.PersistentOpens in a new tab の省略形です。ここで、すべて大文字の項目はパラメータであり、パーセント記号で始まる項目はメソッドです。
通常のクラスベースのアプリケーションでは、これらのクラス (および専用のシステム・サブクラス) をベースにしてクラスを定義します。すべてのオブジェクトは、これらのクラスの 1 つから直接または間接継承し、すべてのオブジェクトは、以下のタイプのいずれかです。
-
登録オブジェクトは、%RegisteredObjectOpens in a new tab またはサブクラスのインスタンスです。これらのオブジェクトは作成できますが、保存することはできません。他の 2 つのクラスは %RegisteredObjectOpens in a new tab から継承し、したがって、そのクラスのすべてのパラメータ、メソッドなどを含みます。
-
永続オブジェクトは、%PersistentOpens in a new tab またはサブクラスのインスタンスです。これらのオブジェクトは、作成、保存、オープン、および削除できます。
永続クラスは、Caché SQL を使用してアクセスできるテーブルに自動的に投影されます。次の章では、永続クラスについて詳細に説明します。
-
シリアル・オブジェクトは、%SerialObjectOpens in a new tab またはサブクラスのインスタンスです。シリアル・クラスは、別のオブジェクトのプロパティとして使用するためのものです。これらのオブジェクトは、作成および削除できますが、それらを含むオブジェクトとは別に単独で保存したり、開くことはできません。
これらのオブジェクトは、永続オブジェクトに含まれている場合、SQL に自動的に投影されます。
%DynamicObjectOpens in a new tab クラスと %DynamicArrayOpens in a new tab クラスを使用することで、Caché では、スキーマを持たないオブジェクトと配列の操作もできます。これらのクラスについては、このドキュメントでは説明しません。詳細は、"Caché での JSON の使用法" を参照してください。
オブジェクト・クラスの基本機能
オブジェクト・クラスを使用すると、以下のタスクを実行できます。
-
オブジェクト (クラスのインスタンス) を作成できます。このためには、そのクラスの %New() メソッドを使用します。これは、%RegisteredObjectOpens in a new tab から継承します。
以下はその例です。
set myobj=##class(Sample.Person).%New()
-
プロパティを使用できます。
どのクラスでもプロパティを定義できますが、インスタンスを作成できるのはオブジェクト・クラスのみであるため、プロパティはオブジェクト・クラスでのみ役立ちます。
どのプロパティにも 1 つのリテラル値、オブジェクト (コレクション・オブジェクトの場合がある)、または多次元配列 (この場合はほとんどない) が含まれます。以下は、オブジェクト値プロパティの定義の例です。
Property Home As Sample.Address;
Sample.Address は別のクラスです。以下に、Home プロパティの値を設定する 1 つの方法を示します。
Set myaddress=##class(Sample.Address).%New() Set myaddress.City="Louisville" Set myaddress.Street="15 Winding Way" Set myaddress.State="Georgia" Set myperson=##class(Sample.Person).%New() Set myperson.Home=myaddress
-
そのクラスまたはそのスーパークラスがインスタンス・メソッドを定義する場合、そのクラスのインスタンスのメソッドを呼び出すことができます。以下はその例です。
Method PrintPerson() { Write !, "Name: ", ..Name Quit }
myobj がこのメソッドを定義するクラスのインスタンスである場合、このメソッドを以下のように呼び出すことができます。
Do myobj.PrintPerson()
-
プロパティ値が、そのプロパティ定義で指定されている規則に従っていることを検証できます。
-
すべてのオブジェクトが、そのオブジェクトのすべてのプロパティ値を正規化するインスタンス・メソッド %NormalizeObject() を継承します。多くのデータ型により、同じ値を異なる表現にすることができます。正規化により、値が、そのキャノニック形式、つまり正規化された形式に変換されます。%NormalizeObject() は、この処理が正常に実行されたかどうかによって True または False を返します。
-
すべてのオブジェクトは、インスタンス・メソッド %ValidateObject() を継承し、このメソッドは、プロパティ値がプロパティ定義に従っているかどうかに応じて True または False を返します。
-
すべての永続オブジェクトは、インスタンス・メソッド %Save() を継承します。%Save() インスタンス・メソッドを使用する場合、システムによって %ValidateObject() が最初に呼び出されます。
対照的に、ルーチン・レベルで作業していて、クラスを使用しない場合、コードに、型とその他の入力要件をチェックするロジックが含まれている必要があります。
-
-
コールバック・メソッドを定義して、オブジェクトを作成、変更などするときの追加のカスタムの動作を追加できます。
例えば、クラスのインスタンスを作成するには、そのクラスの %New() メソッドを呼び出します。そのクラスで %OnNew() メソッド (コールバック・メソッド) が定義されている場合、Caché によってそのメソッドも自動的に呼び出されます。以下に簡単な例を示します。
Method %OnNew() As %Status { Write "hi there" Quit $$$OK }
実際のシナリオでは、このコールバックによっていくつかの必須の初期化が実行される場合があります。また、ファイル、または場合によってはグローバルへの書き込みによるログが実行されることもあります。
OREF
オブジェクト・クラスの %New() メソッドは、オブジェクトのデータを格納するための内部のメモリ内の構造を作成し、その構造を指す OREF (オブジェクト参照) を返します。OREF は、ObjectScript の特別な種類の値です。以下の点に留意してください。
-
ターミナルで、OREF を表示すると、数字、次にアット記号、その次にクラスの名前が続いた文字列が表示されます。以下はその例です。
SAMPLES>set myobj=##class(Sample.Person).%New() SAMPLES>w myobj 3@Sample.Person
-
OREF が必要な場所に OREF が使用されていない場合は、Caché によってエラーが返されます。
SAMPLES>set myobj.Name="Fred Parker" SET myobj.Name="Fred Parker" ^ <INVALID OREF>
以下も同様です。
SAMPLES>do myobj.PrintPerson() DO myobj.PrintPerson() ^ <INVALID OREF>
このエラーを認識できると便利です。これは、変数が OREF である必要があるのに、OREF でないことを意味します。
-
OREF を作成する方法は 1 つのみです。OREF を返すメソッドを使用します。OREF を返すメソッドは、オブジェクト・クラスまたはそれらのサブクラスで定義されます。
以下は、OREF を作成せず、OREF に類似した文字列を作成します。
SAMPLES>set testthis="4@Sample.Person"
-
変数に OREF が含まれているかどうかをプログラムで判別できます。関数 $IsObject は、変数に OREF が含まれている場合に 1 (True) を、その他の場合に 0 (False) を返します。
ストリーム・インタフェース・クラス
前述のとおり、Caché では、文字列操作の結果を保存するために、一定容量を持つ領域が割り当てられます。割り当てられた容量を超える文字列式が発生すると、<MAXSTRING> エラーとなります。長い文字列を有効化していない限り、この上限は 32 KB であり、文字列プロパティを約 32 KB より大きくすることはできません。(他のプロパティもこの上限を超えることはできませんが、長い文字列の上限が適用される前に他の制限が適用されます。)
長い文字列値を渡す必要がある場合や、プロパティに長い文字列値を含める必要がある場合は、ストリームを使用します。ストリームは、文字列サイズの制限を超える単一の値を含むことができるオブジェクトです。(内部で Caché によって、一時的なグローバルが作成および使用されて、メモリの制限が回避されます。)
Caché SQL では、ストリーム・フィールドを使用できますが、いくつかの制限があります。詳細と完全な概要については、"Caché オブジェクトの使用法" を参照してください。また、これらのクラスのインターシステムズ・クラス・リファレンスも参照してください。
ストリーム・クラス
Caché の主要なストリーム・クラスでは、%Stream.ObjectOpens in a new tab クラスによって定義される共通のストリーム・インタフェースを使用します。通常、ストリームは他のオブジェクトのプロパティとして使用し、それらのオブジェクトを保存します。ストリーム・データは、選択するクラスに応じて、外部ファイルまたは Caché グローバルのいずれかに保存できます。
-
%Stream.FileCharacterOpens in a new tab クラスおよび %Stream.FileBinaryOpens in a new tab クラスは、外部ファイルに書き込まれるストリームに対して使用されます。
(バイナリ・ストリームは、%BinaryOpens in a new tab タイプと同種のデータを含み、写真などの大規模なバイナリ・オブジェクトを格納します。文字ストリームは、%StringOpens in a new tab タイプと同種のデータを含み、大量のテキストの保存を目的としています。)
-
%Stream.GlobalCharacterOpens in a new tab クラスおよび %Stream.GlobalBinaryOpens in a new tab クラスは、グローバルに保存されたストリームに対して使用されます。
ストリーム・オブジェクトを操作するには、そのメソッドを使用します。例えば、ストリームにデータを追加するにはこれらのクラスの Write() メソッドを使用し、それからデータを読み取るには Read() を使用します。ストリーム・インタフェースには、Rewind() や MoveTo() などの他のメソッドが含まれます。
例
例えば、以下のコードは、グローバル文字ストリームを作成し、データをそれに書き込みます。
Set mystream=##class(%Stream.GlobalCharacter).%New()
Do mystream.Write("here is some text to store in the stream ")
Do mystream.Write("here is some more text")
Write "this stream has this many characters: ",mystream.Size,!
Write "this stream has the following contents: ",!
Write mystream.Read()
コレクション・クラス
一連の関連する値のためのコンテナが必要な場合は、このドキュメントで前述したように、$LIST フォーマット・リストおよび多次元配列を使用できます。
クラスを使用したい場合、Caché にはリスト・クラスと配列クラスがあります。これらをコレクションといいます。
スタンドアロン・オブジェクトとして使用するリストおよび配列クラス
リスト・オブジェクトを作成するには、以下のクラスを使用します。
-
%Library.ListOfDataTypesOpens in a new tab — リテラル値のリストを定義します。
-
%Library.ListOfObjectsOpens in a new tab — オブジェクト (永続またはシリアル) のリストを定義します。
リスト・オブジェクトを操作するには、そのメソッドを使用します。以下はその例です。
Set Colors=##class(%Library.ListOfDataTypes).%New()
Do Colors.Insert("Red")
Do Colors.Insert("Green")
Do Colors.Insert("Blue")
Write "Number of items in this list: ", Colors.Count()
Write !, "Second item in the list: ", Colors.GetAt(2)
同様に、配列オブジェクトを作成するには、以下のクラスを使用します。
-
%Library.ArrayOfDataTypesOpens in a new tab — リテラル値の配列を定義します。各配列項目には、キーと値があります。
-
%Library.ArrayOfObjectsOpens in a new tab — オブジェクト (永続またはシリアル) の配列を定義します。各配列項目には、キーとオブジェクト値があります。
配列オブジェクトを操作するには、そのメソッドを使用します。以下はその例です。
Set ItemArray=##class(%Library.ArrayOfDataTypes).%New()
Do ItemArray.SetAt("example item","alpha")
Do ItemArray.SetAt("another item","beta")
Do ItemArray.SetAt("yet another item","gamma")
Do ItemArray.SetAt("still another item","omega")
Write "Number of items in this array: ", ItemArray.Count()
Write !, "Item that has the key gamma: ", ItemArray.GetAt("gamma")
プロパティとしてのリストおよび配列
プロパティをリストまたは配列として定義することもできます。
プロパティをリストとして定義するには、以下の形式を使用します。
Property MyProperty As list of Classname;
Classname がデータ型クラスの場合、Caché は %Collection.ListOfDTOpens in a new tab によって提供されるインタフェースを使用します。Classname がオブジェクト・クラスの場合は、%Collection.ListOfObjOpens in a new tab によって提供されるインタフェースを使用します。
プロパティを配列として定義するには、以下の形式を使用します。
Property MyProperty As Array of Classname;
Classname がデータ型クラスの場合、Caché は %Collection.ArrayOfDTOpens in a new tab によって提供されるインタフェースを使用します。Classname がオブジェクト・クラスの場合は、%Collection.ArrayOfObjOpens in a new tab によって提供されるインタフェースを使用します。
便利な ObjectScript 関数
ObjectScript は、オブジェクト・クラスで使用する以下の関数を提供します。
-
$CLASSMETHOD では、クラス名およびメソッド名を指定することでクラス・メソッドを実行できます。以下はその例です。
SAMPLES>set class="Sample.Person" SAMPLES>set obj=$CLASSMETHOD(class,"%OpenId",1) SAMPLES>w obj.Name Van De Griek,Charlotte M.
この関数は、クラス・メソッドを実行する汎用コードを作成する必要があるが、クラス名 (またはメソッド名) が事前にわからない場合に便利です。以下はその例です。
//read name of class from imported document Set class=$list(headerElement,1) // create header object Set headerObj=$classmethod(class,"%New")
他の関数も同様のシナリオで便利です。
-
$METHOD では、インスタンスおよびメソッド名を指定することでインスタンス・メソッドを実行できます。以下はその例です。
SAMPLES>set obj=##class(Sample.Person).%OpenId(1) SAMPLES>do $METHOD(obj,"PrintPerson") Name: Van De Griek,Charlotte M.
-
$PROPERTY は、指定されたインスタンスの指定されたプロパティの値を取得または設定します。以下はその例です。
SAMPLES>set obj=##class(Sample.Person).%OpenId(2) SAMPLES>write $property(obj,"Name") Edison,Patrick J.
-
$PARAMETER は、指定されたインスタンスの指定されたクラス・パラメータの値を取得します。以下はその例です。
SAMPLES>set obj=##class(Sample.Person).%OpenId(2) SAMPLES>write $parameter(obj,"EXTENTQUERYSPEC") Name,SSN,Home.City,Home.State
-
$CLASSNAME は、指定されたインスタンスのクラス名を返します。以下はその例です。
SAMPLES>set obj=##class(Sample.Person).%OpenId(1) SAMPLES>write $CLASSNAME(obj) Sample.Person
引数がない場合、この関数は現在のコンテキストのクラス名を返します。これは、インスタンス・メソッドで便利です。
詳細
この章で説明したトピックの詳細は、以下のドキュメントを参照してください。
-
"Caché オブジェクトの使用法" には、Caché でのクラスおよびクラス・メンバの定義方法についての説明があります。
-
"Caché クラス定義リファレンス" には、クラス定義で使用するコンパイラ・キーワードのリファレンス情報があります。
-
“インターシステムズ・クラス・リファレンス” で後述するインターシステムズ・クラス・リファレンスには、Caché で提供されるすべての非内部クラスの詳細な情報があります。