オブジェクト
ここでは、InterSystems IRIS® データ・プラットフォームのオブジェクトについて説明します。
このページで示されているコード・サンプルでは、Samples-Data サンプル (https://github.com/intersystems/Samples-DataOpens in a new tab) のクラスを使用しています。サンプルは、専用のネームスペース (SAMPLES など) を作成して、そのネームスペースにロードすることをお勧めします。一般的な手順は、"InterSystems IRIS で使用するサンプルのダウンロード" を参照してください。
InterSystems IRIS オブジェクト・クラスの概要
InterSystems IRIS は、%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 またはサブクラスのインスタンスです。これらのオブジェクトは、作成、保存、オープン、および削除できます。
永続クラスは、InterSystems SQL を使用してアクセスできるテーブルへ自動的に投影されます。
-
シリアル・オブジェクトは、%SerialObjectOpens in a new tab またはサブクラスのインスタンスです。シリアル・クラスは、別のオブジェクトのプロパティとして使用するためのものです。これらのオブジェクトを作成することはできますが、オブジェクトを保存したり、それらを含むオブジェクトとは別に単独で開いたりすることはできません。
これらのオブジェクトは、永続オブジェクトに含まれている場合、SQL に自動的に投影されます。
%DynamicObjectOpens in a new tab クラスと %DynamicArrayOpens in a new tab クラスを使用することで、InterSystems IRIS では、スキーマを持たないオブジェクトと配列の操作もできます。詳細は、"JSON の使用" を参照してください。
オブジェクト・クラスの基本機能
オブジェクト・クラスを使用すると、以下のタスクを実行できます。
-
オブジェクト (クラスのインスタンス) を作成できます。このためには、そのクラスの %New() メソッドを使用します。これは、%RegisteredObjectOpens in a new tab から継承します。
以下に例を示します。
set myobj=##class(Sample.Person).%New()
myobj = iris.cls("Sample.Person")._New()
Python メソッド名ではパーセント記号 (%) を使用できません。% 文字が含まれる ObjectScript メソッドを Python から呼び出すには、上の例のように % 文字をアンダースコア (_) に置き換えます。
-
プロパティを使用できます。
どのクラスでもプロパティを定義できますが、インスタンスを作成できるのはオブジェクト・クラスのみであるため、プロパティはオブジェクト・クラスでのみ役立ちます。
どのプロパティにも 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
import iris myaddress=iris.cls("Sample.Address")._New() myaddress.City="Louisville" myaddress.Street="15 Winding Way" myaddress.State="Georgia" myperson=iris.cls("Sample.Person")._New() myperson.Home=myaddress
-
そのクラスまたはそのスーパークラスがインスタンス・メソッドを定義する場合、そのクラスのインスタンスのメソッドを呼び出すことができます。以下に例を示します。
Method PrintPerson() [ Language = objectscript ] { Write !, "Name: ", ..Name }
Method PrintPerson() [ Language = python ] { print("\nName:", self.Name) }
myobj がこのメソッドを定義するクラスのインスタンスである場合、このメソッドを以下のように呼び出すことができます。
Do myobj.PrintPerson()
myobj.PrintPerson()
-
プロパティ値が、そのプロパティ定義で指定されている規則に従っていることを検証できます。
-
すべてのオブジェクトが、そのオブジェクトのすべてのプロパティ値を正規化するインスタンス・メソッド %NormalizeObject() を継承します。多くのデータ型により、同じ値を異なる表現にすることができます。正規化により、値が、そのキャノニック形式、つまり正規化された形式に変換されます。%NormalizeObject() は、この処理が正常に実行されたかどうかによって True または False を返します。
-
すべてのオブジェクトは、インスタンス・メソッド %ValidateObject() を継承し、このメソッドは、プロパティ値がプロパティ定義に従っているかどうかに応じて True または False を返します。
-
すべての永続オブジェクトは、インスタンス・メソッド %Save() を継承します。%Save() インスタンス・メソッドを使用する場合、システムによって %ValidateObject() が最初に呼び出されます。
対照的に、ルーチン・レベルで作業していて、クラスを使用しない場合、コードに、型とその他の入力要件をチェックするロジックが含まれている必要があります。
-
-
コールバック・メソッドを定義して、オブジェクトを作成、変更などするときの追加のカスタムの動作を追加できます。
例えば、クラスのインスタンスを作成するには、そのクラスの %New() メソッドを呼び出します。そのクラスで %OnNew() メソッド (コールバック・メソッド) が定義されている場合、InterSystems IRIS によってそのメソッドも自動的に呼び出されます。簡単な例を以下に示します。
Method %OnNew() As %Status { Write "hi there" Return $$$OK }
Method %OnNew() As %Status [ Language = python ] { print("hi there") return True }
実際のシナリオでは、このコールバックによっていくつかの必須の初期化が実行される場合があります。また、ファイル、または場合によってはグローバルへの書き込みによるログが実行されることもあります。
OREF
オブジェクト・クラスの %New() メソッドは、オブジェクトのデータを格納するための内部のメモリ内の構造を作成し、その構造を指す OREF (オブジェクト参照) を返します。OREF は、InterSystems IRIS の特別な種類の値です。以下の点に留意してください。
-
ターミナルでは、OREF の内容は使用する言語によって異なります。
-
ObjectScript では、数字、次にアット記号 (@)、その次にクラスの名前が続いた文字列が表示されます。
-
Python では、クラス名と、メモリ内の固有の場所を示す 18 文字を含む文字列が表示されます。
以下に例を示します。
TESTNAMESPACE>set myobj=##class(Sample.Person).%New() TESTNAMESPACE>w myobj 3@Sample.Person
>>> myobj=iris.cls("Sample.Person")._New() >>> print(myobj) <iris.Sample.Person object at 0x000001A1E52FFD20>
-
-
OREF が必要な場所で OREF を使用していない場合や、不適切なタイプの OREF を使用した場合、InterSystems IRIS はエラーを返します。このエラーは、ObjectScript ターミナルと Python ターミナルで異なります。
TESTNAMESPACE>set x=2 TESTNAMESPACE>set x.Name="Fred Parker" SET x.Name="Fred Parker" ^ <INVALID OREF>
>>> x=2 >>> x.Name="Fred Parker" Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'int' object has no attribute 'Name'
このエラーを認識できると便利です。これは、変数が OREF である必要があるのに、OREF でないことを意味します。
-
OREF を作成する方法は 1 つのみです。OREF を返すメソッドを使用します。OREF を返すメソッドは、オブジェクト・クラスまたはそれらのサブクラスで定義されます。
以下は、OREF を作成せず、OREF に類似した文字列を作成します。
TESTNAMESPACE>set testthis="4@Sample.Person"
>>> testthis="<iris.Sample.Person object at 0x000001A1E52FFD20>"
-
ObjectScript では、変数に OREF が含まれているかどうかをプログラムで判別できます。関数 $IsObject は、変数に OREF が含まれている場合に 1 (True) を、その他の場合に 0 (False) を返します。
ストリーム・インタフェース・クラス
InterSystems IRIS では、文字列操作の結果を保存するために、一定容量を持つ領域が割り当てられます。割り当てられた容量を超える文字列式が発生すると、<MAXSTRING> エラーとなります。"文字列長の制限" を参照してください。
この上限を超える長さの値を渡す必要がある場合や、この上限を超える可能性のある値を持つプロパティが必要な場合は、ストリームを使用します。ストリームは、文字列サイズの制限を超える単一の値を含むことができるオブジェクトです。(内部で InterSystems IRIS によって、一時的なグローバルが作成および使用されて、メモリの制限が回避されます。)
InterSystems SQL では、ストリーム・フィールドを使用できますが、いくつかの制限があります。詳細と完全な概要については、"クラスの定義と使用" を参照してください。また、これらのクラスのインターシステムズ・クラス・リファレンスも参照してください。
Python で ObjectScript ストリーム・フィールドを使用することはできません。
ストリーム・クラス
InterSystems IRIS の主要なストリーム・クラスでは、%Stream.ObjectOpens in a new tab クラスによって定義される共通のストリーム・インタフェースを使用します。通常、ストリームは他のオブジェクトのプロパティとして使用し、それらのオブジェクトを保存します。ストリーム・データは、選択するクラスに応じて、外部ファイルまたは InterSystems IRIS グローバルのいずれかに保存できます。
-
%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 フォーマット・リストおよび多次元配列を使用できます。
クラスを使用したい場合、InterSystems IRIS にはリスト・クラスと配列クラスがあります。これらをコレクションといいます。コレクションの詳細は、"コレクションを使用した作業" を参照してください。
スタンドアロン・オブジェクトとして使用するリストおよび配列クラス
リスト・オブジェクトを作成するには、以下のクラスを使用します。
-
%Library.ListOfDataTypesOpens in a new tab — リテラル値のリストを定義します。
-
%Library.ListOfObjectsOpens in a new tab — オブジェクト (永続またはシリアル) のリストを定義します。
リスト内の要素は順番に並べられます。リスト内での要素の位置には、1 から N までの範囲の整数のキーを使用してアクセスできます。N は最後の要素の位置です。
リスト・オブジェクトを操作するには、そのメソッドを使用します。以下に例を示します。
set Colors = ##class(%Library.ListOfDataTypes).%New()
do Colors.Insert("Red")
do Colors.Insert("Green")
do Colors.Insert("Blue")
write "Number of list items: ", Colors.Count()
write !, "Second list item: ", Colors.GetAt(2)
do Colors.SetAt("Yellow",2)
write !, "New second item: ", Colors.GetAt(2)
write !, "Third item before insertion: ", Colors.GetAt(3)
do Colors.InsertAt("Purple",3)
write !, "Number of items after insertion: ", Colors.Count()
write !, "Third item after insertion: ", Colors.GetAt(3)
write !, "Fourth item after insertion: ", Colors.GetAt(4)
do Colors.RemoveAt(3)
write "Number of items after removing item 3: ", Colors.Count()
write "List items:"
for i = 1:1:Colors.Count() write Colors.GetAt(i),!
import iris
Colors=iris.cls("%Library.ListOfDataTypes")._New()
Colors.Insert("Red")
Colors.Insert("Green")
Colors.Insert("Blue")
print("Number of list items:", Colors.Count())
print("Second list item:", Colors.GetAt(2))
Colors.SetAt("Yellow",2)
print("New second item: ", Colors.GetAt(2))
print("Third item before insertion: ", Colors.GetAt(3))
Colors.InsertAt("Purple",3)
print("Number of items after insertion: ", Colors.Count())
print("Third item after insertion: ", Colors.GetAt(3))
print("Fourth item after insertion: ", Colors.GetAt(4))
Colors.RemoveAt(3)
print("Number of items after removing item 3: ", Colors.Count())
print("List items:")
for i in range(1, Colors.Count() + 1) print(Colors.GetAt(i))
同様に、配列オブジェクトを作成するには、以下のクラスを使用します。
-
%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")
import iris
ItemArray=iris.cls("%Library.ArrayOfDataTypes")._New()
ItemArray.SetAt("example item", "alpha")
ItemArray.SetAt("another item", "beta")
ItemArray.SetAt("yet another item", "gamma")
ItemArray.SetAt("still another item", "omega")
print("Number of items in this array:", ItemArray.Count())
print("Item that has the key gamma:", ItemArray.GetAt("gamma"))
SetAt() メソッドは項目を配列に追加します。最初の引数は追加する要素、2 つ目の引数はキーです。配列要素は、キーの順に並べられます。最初は数値キーで、小さい数値から大きい数値の順に並べられ、次に文字列キーで、アルファベット順に大文字の後に小文字という順に並べられます。例 : -2、-1、0、1、2、A、AA、AB、a、aa、ab。
プロパティとしてのリストおよび配列
プロパティをリストまたは配列として定義することもできます。
プロパティをリストとして定義するには、以下の形式を使用します。
Property MyProperty as list of Classname;
Classname がデータ型クラスの場合、InterSystems IRIS は %Collection.ListOfDTOpens in a new tab によって提供されるインタフェースを使用します。Classname がオブジェクト・クラスの場合は、%Collection.ListOfObjOpens in a new tab によって提供されるインタフェースを使用します。
プロパティを配列として定義するには、以下の形式を使用します。
Property MyProperty as array of Classname;
Classname がデータ型クラスの場合、InterSystems IRIS は %Collection.ArrayOfDTOpens in a new tab によって提供されるインタフェースを使用します。Classname がオブジェクト・クラスの場合は、%Collection.ArrayOfObjOpens in a new tab によって提供されるインタフェースを使用します。
便利な ObjectScript 関数
ObjectScript は、オブジェクト・クラスで使用する以下の関数を提供します。
-
$CLASSMETHOD では、クラス名およびメソッド名を指定することでクラス・メソッドを実行できます。以下に例を示します。
TESTNAMESPACE>set class="Sample.Person" TESTNAMESPACE>set obj=$CLASSMETHOD(class,"%OpenId",1) TESTNAMESPACE>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 では、インスタンスおよびメソッド名を指定することでインスタンス・メソッドを実行できます。以下に例を示します。
TESTNAMESPACE>set obj=##class(Sample.Person).%OpenId(1) TESTNAMESPACE>do $METHOD(obj,"PrintPerson") Name: Van De Griek,Charlotte M.
-
$PROPERTY は、指定されたインスタンスの指定されたプロパティの値を取得または設定します。以下に例を示します。
TESTNAMESPACE>set obj=##class(Sample.Person).%OpenId(2) TESTNAMESPACE>write $property(obj,"Name") Edison,Patrick J.
-
$PARAMETER は、指定されたインスタンスの指定されたクラス・パラメータの値を取得します。以下に例を示します。
TESTNAMESPACE>set obj=##class(Sample.Person).%OpenId(2) TESTNAMESPACE>write $parameter(obj,"EXTENTQUERYSPEC") Name,SSN,Home.City,Home.State
-
$CLASSNAME は、指定されたインスタンスのクラス名を返します。以下に例を示します。
TESTNAMESPACE>set obj=##class(Sample.Person).%OpenId(1) TESTNAMESPACE>write $CLASSNAME(obj) Sample.Person
引数がない場合、この関数は現在のコンテキストのクラス名を返します。これは、インスタンス・メソッドで便利です。
関連項目
このページで説明したトピックの詳細は、以下のリソースを参照してください。
-
"クラスの定義と使用" では、InterSystems IRIS でのクラスおよびクラス・メンバの定義方法について説明しています。
-
"クラス定義リファレンス" には、クラス定義で使用するコンパイラ・キーワードのリファレンス情報があります。
-
"インターシステムズ・クラス・リファレンス" には、InterSystems IRIS で提供されるすべての非内部クラスに関する詳細があります。