Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

クラスの定義とコンパイル

この章では、クラスの定義とコンパイルに関する基本的な事項について説明します。以下のトピックについて説明します。

このドキュメントをオンラインで表示している場合は、このドキュメントの "序文" を使用すると、他のトピックをすばやく見つけることができます。

用語の概要

以下に、簡単な Caché クラス定義と、いくつかの代表的な要素を示します。

Class Demo.MyClass Extends %RegisteredObject
{

Property Property1 As %String;

Property Property2 As %Numeric;

Method MyMethod() As %String
{
   set returnvalue=..Property1_..Property2
   quit returnvalue
}

}

以下の点に注意してください。

  • 完全なクラス名は Demo.MyClass です。パッケージ名は Demo、短いクラス名は MyClass です。

  • このクラスは、クラス %RegisteredObjectOpens in a new tab を拡張しています。同様に、このクラスは、%RegisteredObjectOpens in a new tab を継承しています。

    %RegisteredObjectOpens in a new tab は、このクラスのスーパークラスです。つまり、このクラスは、%RegisteredObjectOpens in a new tab のサブクラスになります。Caché クラスは、この章で後述するように、複数のスーパークラスを持つことができます。

    クラスのスーパークラスにより、そのクラスの用途が決まります。

  • このクラスでは、2 つのプロパティ Property1Property2 を定義しています。プロパティ Property1 のタイプは %StringOpens in a new tab です。また、プロパティ Property2 のタイプは %NumericOpens in a new tab です。

  • このクラスでは、1 つのメソッド MyMethod() を定義しています。このメソッドは、%StringOpens in a new tab タイプの値を返します。

このクラスでは、Caché が提供するシステム・クラスを参照しています。これに該当するクラスは、%RegisteredObjectOpens in a new tab (完全名は %Library.RegisteredObjectOpens in a new tab)、%StringOpens in a new tab (%Library.StringOpens in a new tab)、および %NumericOpens in a new tab (%Library.NumericOpens in a new tab) です。%RegisteredObjectOpens in a new tab は、オブジェクト・インタフェースを定義しているため、Caché の重要なクラスの 1 つといえます。これにより、オブジェクト・インスタンスを作成するメソッドとオブジェクト・インスタンスを操作するメソッドが提供されます。%StringOpens in a new tab%NumericOpens in a new tab はデータ型クラスです。そのため、それに対応するプロパティは、リテラル値を保持することになります (その他の種類の値は保持しません)。

クラスの種類

Caché には、クラス定義の大規模セットが用意されています。これは、以下のような一般的な方法でクラスで使用できます。

  • Caché クラスは、クラスのスーパークラスとして使用できます。

  • Caché クラスは、例えば、プロパティの値として、メソッドへの引数の値として、メソッドから返される値などとして使用できます。

  • Caché クラスには、特定の API を提供するだけのものがあります。通常、このようなクラスは、上記のいずれの方法でも使用してはいけません。その代わりに、API のメソッドを呼び出すコードを作成してください。

スーパークラスの最も一般的な選択項目は、以下のとおりです。

  • %RegisteredObjectOpens in a new tab — このクラスは、最も汎用的な形式でオブジェクト・インタフェースを表します。

  • %PersistentOpens in a new tab — このクラスは、永続クラスを表します。オブジェクト・インタフェースを提供することに加え、このクラスは、データベースにオブジェクトを保存するためのメソッドと、データベースからオブジェクトを読み取るためのメソッドも提供します。

  • %SerialObjectOpens in a new tab — このクラスは、別のオブジェクトに埋め込み可能な (別のオブジェクト内でシリアル化できる) オブジェクトを表します。

  • 上記のクラスのいずれかのサブクラス。

  • なし — クラスを作成するときに、スーパークラスを指定する必要はありません。

プロパティの値、メソッドへの引数の値、メソッドから返される値などについて、最も一般的な選択項目は以下のとおりです。

  • オブジェクト・クラス (前述のリストに含まれるクラス)

  • データ型クラス

  • コレクション・クラス

  • ストリーム・クラス

このドキュメントの後半の章では、クラスのこのようなカテゴリについて説明しています。

オブジェクト・クラス

オブジェクト・クラスとは、%RegisteredObjectOpens in a new tab のサブクラスを指す語句です。オブジェクト・クラスでは、クラスのインスタンスの作成、インスタンスのプロパティの指定、およびインスタンスのメソッドの呼び出しができます。後出の章では、このようなタスクについて説明しています (また、すべてのオブジェクト・クラスに適用される情報についても説明しています)。

オブジェクトとは、オブジェクト・クラスのインスタンスを指す一般的な用語です。

オブジェクト・クラスには、3 つの一般的なカテゴリがあります。

以下の図は、これら 3 つのクラス間の継承関係を示しています。ボックスには、クラスで定義されたメソッドのいくつかをリストしています。

generated description: objclasses

コレクション・クラスとストリーム・クラスは、シリアル化の動作を備えたオブジェクト・クラスです。

データ型クラス

データ型クラスとは、ClassType キーワードが datatype に設定されているクラス、または、そのようなクラスのサブクラスのことを指す語句です。これに該当するクラスは、オブジェクト・クラスではありません (データ型クラスでは、プロパティを定義できません。また、クラスのインスタンスを作成できません)。データ型クラス (より厳密には、データ型ジェネレータ・クラス) の用途は、オブジェクト・クラスのプロパティのタイプとして使用することです。

クラス・メンバの種類

Caché クラスの定義には、以下の項目を含めることができ、これらはすべてクラス・メンバと呼ばれます。

  • パラメータ — パラメータは、このクラスによって使用される定数値を定義します。ほとんどの場合、この値はコンパイル時に設定されます。

  • メソッド — Caché は、インスタンス・メソッドとクラス・メソッドの 2 種類のメソッドをサポートしています。インスタンス・メソッドは、クラスの特定のインスタンスから呼び出され、そのインスタンスに関連する何らかのアクションを実行します。このタイプのメソッドは、オブジェクト・クラス内でのみ役立ちます。クラス・メソッドは、そのクラスのインスタンスがメモリ内にあるかどうかにかかわらず、呼び出すことがでます。このタイプのメソッドは、他の言語では静的メソッドと呼ばれています。

  • プロパティ — プロパティには、クラスのインスタンスのデータが格納されます。プロパティは、オブジェクト・クラスでのみ役立ちます。詳細は、以下のサブセクションで説明します。

  • クラス・クエリ — クラス・クエリは、クラスが使用できる SQL クエリを定義し、クエリのためのコンテナとして使用するクラスを指定します。多くの場合 (必須ではない)、永続クラスには、クラス・クエリを定義します。これは、そのクラスの保存済みデータにクエリを実行するためのものです。ただし、クラス・クエリは、どのようなクラスにでも定義できます。

  • その他の種類のクラス・メンバ (永続クラスにのみ関連するメンバ) :

    • ストレージ定義

    • インデックス

    • 外部キー

    • SQL トリガ

  • XData ブロック — XData ブロックは、クラス内の整形式 XML ドキュメントです。通常、クラスのメソッドで使用します。これらには、多数の用途があります。

  • プロジェクション — クラス・プロジェクションは、クラス・コンパイラの動作を拡張する方法を提供します。

    プロジェクションのメカニズムは、Java および C++ のプロジェクションで使用されます。これが、プロジェクションという用語の語源です。

プロパティの種類

形式上、プロパティには、属性およびリレーションシップという 2 種類のプロパティがあります。

属性は値を保持します。属性プロパティは、通常、単にプロパティと呼びます。プロパティの定義に応じて、保持できる値は、以下のいずれかにできます。

  • リテラル値 ("MyString" や 1 など)。リテラル値を保持するプロパティは、データ型クラスに基づいているため、データ型プロパティと呼ばれることもあります。“リテラル・プロパティの定義と使用” の章を参照してください。

  • ストリーム。ストリームとは、文字列には長すぎる値を格納する Caché オブジェクトです。“ストリームを使用した作業” の章を参照してください。

  • コレクション。Caché には、プロパティをリストまたは配列として定義する機能があります。リストまたは配列の項目は、リテラル値になるか、オブジェクトにできます。“コレクションを使用した作業” の章を参照してください。

  • その他の種類のオブジェクト。“オブジェクト値プロパティの定義と使用” の章を参照してください。

リレーションシップは、オブジェクト間の関連付けを保持します。リレーションシップ・プロパティはリレーションシップと呼ばれます。リレーションシップは、永続クラスでのみサポートされます。“リレーションシップの定義と使用” の章を参照してください。

クラスの定義法:基本

このセクションでは、基本的なクラス定義について詳細に説明します。以下のトピックについて説明します。

クラスの定義には、一般的にスタジオを使用します。Caché クラス定義クラスまたは XML クラス定義ファイルを使用して、プログラム的にクラスを定義することもできます。SQL DDL 文を使用して SQL テーブルを定義する場合、システムはそれに対応するクラス定義を作成します。

スーパークラスの選択

クラスを定義する場合、設計上の最初の決定事項の 1 つは、独自のクラスのベースにするクラス (複数可) を選択することです。スーパークラスが 1 つのみの場合は、Extends に続けてスーパークラスの名前をクラス定義の冒頭部分に含めます。

Class Demo.MyClass Extends Superclass 
{

//...

}

スーパークラスが複数ある場合は、それらをコンマ区切りのリストとして、括弧で囲って指定します。

Class Demo.MyClass Extends (Superclass1, Superclass2, Superclass3) 
{

//...

}

クラスを作成するときに、スーパークラスを指定する必要はありません。一般に、クラスがどのような種類のオブジェクトも表現しないとしても、共通に使用される多数のマクロにクラスからアクセスできるようにするために、スーパークラスとして %RegisteredObjectOpens in a new tab を使用します。その代わりに、それらが格納されたインクルード・ファイルを直接取り込むこともできます。

インクルード・ファイル

%RegisteredObjectOpens in a new tab またはそのサブクラスを拡張しないクラスを作成するときには、以下のインクルード・ファイルを取り込むことができます。

  • %occStatus.inc%StatusOpens in a new tab の値を操作するためのマクロが定義されています。

  • %occMessages.inc。メッセージを操作するためのマクロが定義されています。

    これらのインクルード・ファイルで定義されているマクロの詳細は、"Caché ObjectScript の使用法" の “システムにより提供されるマクロの使用” を参照してください。

%RegisteredObjectOpens in a new tab またはそのサブクラスを拡張するクラスの場合は、これらのマクロが自動的に利用できるようになります。

また、独自のインクルード・ファイルを作成して、そのファイルを必要に応じてクラス定義に取り込むことができます。

クラス定義の先頭にインクルード・ファイルを取り込むには、以下の形式の構文を使用します。インクルード・ファイルの拡張子 .inc は省略する必要がある点に注意してください。

Include MyMacros

例 :

Include %occInclude

Class Classname 
{
}

クラス定義の先頭に複数のインクルード・ファイルを取り込むには、以下の形式の構文を使用します。

Include (MyMacros, YourMacros) 

この構文では、先頭にシャープ記号が付かない点に注意してください (習慣的に必要とする構文とは異なります)。また、Include 指示文は、大文字と小文字が区別されません。例えば、INCLUDE を使用することも可能です。インクルード・ファイルの名前は、大文字と小文字が区別されます。

"Caché ObjectScript の使用法" で "#Include" にある参照セクションも参照してください。

クラス・キーワードの指定

場合によっては、クラス・コンパイラが生成するコードの詳細を制御することが必要になります。例えば、永続クラスについて、既定のテーブル名の使用を望まない場合 (または使用できない場合) は、SQL テーブルの名前を指定できます。もう 1 つ例を挙げると、クラスに Final のマークを付けて、そのクラスのサブクラスが作成されないようにすることもできます。クラス定義では、そのような目的に応じた特定のキーワードのセットをサポートしています。クラス・キーワードの指定が必要な場合は、以下に示すように、スーパークラスの後の角括弧でクラス・キーワードを囲みます。

Class Demo.MyClass Extends Demo.MySuperclass [ Keyword1, Keyword2, ...]
{

//...

}

例えば、使用可能なクラス・キーワードには、AbstractFinal があります。概要については、この章で後述する “コンパイラ・キーワード” を参照してください。Caché には、各種のクラス・メンバに固有のキーワードも用意されています。

クラス・パラメータの定義法の概要

クラス・パラメータは、特定のクラスのすべてのオブジェクトに対する定数値を定義します。クラス・パラメータをクラス定義に追加するには、以下のいずれかのような要素をクラスに追加します。

Parameter PARAMNAME as Type;
Parameter PARAMNAME as Type = value;
Parameter PARAMNAME as Type [ Keywords ] = value;

Keywords はパラメータ・キーワードを表します。キーワードの概要については、この章で後述する “コンパイラ・キーワード” を参照してください。パラメータ・キーワードについては、"Caché クラス定義リファレンス" の “Parameter キーワード” を参照してください。これはオプションです。

プロパティの定義法の概要

オブジェクト・クラスには、プロパティを含めることができます。

プロパティをクラス定義に追加するには、以下のいずれかのような要素をクラスに追加します。

Property PropName as Classname;
Property PropName as Classname [ Keywords ] ;
Property PropName as Classname(PARAM1=value,PARAM2=value) [ Keywords ] ;
Property PropName as Classname(PARAM1=value,PARAM2=value) ;

PropName はプロパティの名前です。Classname はオプションのクラス名です (これを省略すると、プロパティのタイプは %StringOpens in a new tab になると想定されます)。

Keywords はプロパティ・キーワードを表します。キーワードの概要については、この章で後述する “コンパイラ・キーワード” を参照してください。プロパティ・キーワードについては、"Caché クラス定義リファレンス" の “Property キーワード” を参照してください。これはオプションです。

プロパティで使用するクラスによっては、3 番目と 4 番目のバリエーションに示すように、プロパティ・パラメータも指定できるようになります。

プロパティ・パラメータを含める場合は、パラメータを括弧で囲み、プロパティ・キーワードの前に置きます。プロパティ・キーワードを含める場合、キーワードは角括弧で囲む点にも注意してください。

メソッドの定義法の概要

Caché クラスには、クラス・メソッドとインスタンス・メソッドという 2 種類のメソッドを定義できます。

クラス・メソッドをクラス定義に追加するには、以下に示すような要素をクラスに追加します。

ClassMethod MethodName(arguments) as Classname [ Keywords]
{
//method implementation
}

MethodName はメソッドの名前です。また、arguments は引数のコンマ区切りリストです。Classname は、このメソッドで返される値 (ある場合) のタイプを表す、オプションのクラス名です。メソッドが値を返さない場合は、As Classname 部分を省略します。

Keywords はメソッド・キーワードを表します。キーワードの概要については、この章で後述する “コンパイラ・キーワード” を参照してください。メソッド・キーワードについては、"Caché クラス定義リファレンス" の “Method キーワード” を参照してください。これはオプションです。

インスタンス・メソッドを追加するには、同じ構文で ClassMethod の代わりに Method を使用します。

Method MethodName(arguments) as Classname [ Keywords]
{
//method implementation
}

インスタンス・メソッドは、オブジェクト・クラスでのみ存在価値があります。

名前付け規約

クラスとクラス・メンバは、特定の名前付け規約に従います。このセクションでは、名前付け規約の詳細を説明します。

クラス名とクラス・メンバ名の規則

このセクションでは、最大長、許可される文字など、クラス名とメンバ名の規則について説明します。次のセクションで説明するように、完全なクラス名には、そのパッケージ名が含まれます。

すべての識別子は、そのコンテキスト内で一意であることが必要です (つまり、2 つのクラスが同時に同じ名前を持つことはできません)。Caché では、パッケージ、クラス、およびメンバの名前について以下の制限があります。

  • 各パッケージの名前には、189 文字までの一意の文字を含めることができます。

  • 各クラスの名前には、60 文字までの一意の文字を含めることができます。

  • 各メソッドおよびプロパティの名前には、180 文字までの一意の文字を含めることができます。詳細は、“クラス・メンバ名” を参照してください。

  • プロパティの名前の長さと、そのプロパティのインデックスの名前の長さを合わせた長さは、180 文字を超えてはいけません。

  • 各メンバの完全な名前 (未修飾のメンバ名、クラス名、パッケージ名、およびセパレータがあればそれを含む) は、220 文字以下である必要があります。

  • 各名前には Unicode 文字を使用できます。

大文字と小文字は区別されます。つまり、名前の大文字と小文字が正確に一致している必要があります。また、2 つのクラスに、大文字と小文字が異なるだけの同じ名前を付けることはできません。例えば、識別子 “id1” と “ID1” は一意性を保つ目的からは同一と見なされます。

識別子はアルファベット文字で始める必要がありますが、2 文字目以降は数字を含めることもできます。識別子にはスペースや句読点を含むことはできませんが、パッケージ名には “.” 文字を含めることができます。Unicode システムでは、識別子に Unicode 文字を含めることができます。

特定の識別子は “%” で始まり、これはシステム項目であることを示します。例えば、Caché ライブラリに含まれる多くのメソッドやパッケージの名前は、“%” 文字で始まります。

メンバ名の範囲を指定できます。これにより、それ以外では許可されない文字をメンバ名に使用できます。範囲指定したメンバ名を作成するには、名前の最初と最後の文字に二重引用符を使用します。以下はその例です。

Property "My Property" As %String;

システム識別子の詳細は、"Caché プログラミング入門ガイド" の付録 “識別子のルールとガイドライン” を参照してください。

クラス名

すべてのクラスは、一意に識別できる名前を持っています。完全なクラス名は、パッケージ名とクラス名の 2 つの部分で構成されています。名前の中で最後の “.” 文字以降がクラス名になります。クラス名はそのパッケージ内で一意でなければならず、パッケージ名も Caché ネームスペース内で一意である必要があります。パッケージの詳細は、“パッケージ” の章を参照してください。

永続クラスは自動的に SQL テーブルとして投影されるので、クラス定義は SQL 予約語ではないテーブル名を指定する必要があります。 永続クラスの名前が SQL 予約語である場合、クラス定義は SQLTableName キーワードに対して予約語でない有効な値を指定する必要もあります。

クラス・メンバ名

すべてのクラス・メンバ (プロパティやメソッドなど) の名前は、そのクラスの範囲で一意で、180 文字以下の長さとする必要があります。さらに、永続のメンバは、そのメンバの識別子として SQL 予約語を使用できません。ただし、そのメンバの SQLName または SQLFieldName キーワードを使用して、別名を定義することはできます (適切な場合)。

Important:

2 つのメンバに同一の名前を付与しないでください。予測できない結果となる可能性があります。

継承

Caché クラスは、既存のクラスを継承できます。あるクラスを別のクラスから継承する場合、継承して発生するクラスをサブクラスと呼び、その派生元のクラスをスーパークラスと呼びます。

2 つのスーパークラスを使用するクラス定義の例を以下に示します。

Class User.MySubclass Extends (%Library.Persistent, %Library.Populate)
{
}
Note:

ここに示す構文は、Super キーワードに対応します。Super キーワードはスタジオ・インスペクタや、XML としてエクスポートされるクラス定義に表示されます。

スーパークラスからメソッドを継承するクラスに加え、プロパティはシステム・プロパティの動作クラスから追加のメソッドを継承します。また、データ型属性の場合は、データ型クラスから継承します。

例えば、以下の Person という定義済みクラスがあるとします。

Class MyApp.Person Extends %Library.Persistent
{
Property Name As %String;
Property DOB As %Date;
}

このクラスから、新規クラスの Employee を容易に派生できます。

Class MyApp.Employee Extends Person
{
Property Salary As %Integer;
Property Department As %String;
}

この定義は、Employee クラスを Person クラスのサブクラスとして確立するものです。独自のクラス・パラメータやプロパティ、メソッドに加え、Employee クラスは Person クラスからのすべての要素を含みます。

サブクラスの使用

スーパークラスを使用するすべての場所で、サブクラスを使用できます。例えば、上で定義した Employee クラス、および Person クラスを使用すると、Employee オブジェクトを開いて、Person として参照できます。

 Set x = ##class(MyApp.Person).%OpenId(id)
 Write x.Name

以下のように、Employee 固有の属性、またはメソッドにもアクセスできます。

 Write x.Salary // displays the Salary property (only available in Employee instances)

プライマリ・スーパークラス

サブクラスの拡張元の中で最も左側にあるスーパークラスを、そのサブクラスのプライマリ・スーパークラスと呼びます。クラスはそのプライマリ・スーパークラスのすべてのメンバを継承します。このメンバには、該当のクラス・キーワード、プロパティ、メソッド、クエリ、インデックス、クラス・パラメータ、継承したプロパティと継承したメソッドのパラメータとキーワードなどがあります。Final としてマークされている項目を除き、継承したメンバの特性をサブクラスでオーバーライドできます (削除はされません)。

多重継承の詳細は、次のセクションを参照してください。

多重継承

多重継承によって、クラスの動作やクラス・タイプを複数のスーパークラスから継承できます。多重継承を構築するには、括弧内に複数のスーパークラスをリストします。一番左側にあるスーパークラスがプライマリ・スーパークラスになります。

例えば、クラス X がクラス ABC から継承する場合、その定義は以下のようになります。

Class X Extends (A, B, C) 
{
}

クラス・コンパイラの既定の継承順序は左から右なので、スーパークラスどうしでメンバ定義に相違がある場合は、最も左に記述されたスーパークラスを優先することで解決されます (この例では、ABC よりも優先し、BC よりも優先します)。

具体的には、クラス X の場合、クラス・パラメータ値、プロパティ、およびメソッドの値は、クラス A (リストの先頭にあるスーパークラス) から継承され、次にクラス B、最後にクラス C から継承されます。また、X は、A で定義されていないクラス・メンバを B から継承し、A でも B でも定義されていないクラス・メンバを C から継承します。A から既に継承したクラス・メンバと同じ名前のメンバが B にある場合、X では A から継承した値を使用します。同様に、A または B のいずれかから継承したクラス・メンバと同じ名前のメンバが C にある場合は、ABC の優先順位で値を使用します。

既定では左から右への継承になるため、継承順序を指定する必要はありません。そのため、前述のクラス定義の例は、次の場合と等しくなります。

Class X Extends (A, B, C) [ Inheritance = left ]
{
}

スーパークラス間で右から左への継承を指定するには、以下のように Inheritance キーワードを使用して right の値を指定します。

Class X Extends (A, B, C) [ Inheritance = right ]
{
}

右から左への継承では、複数のスーパークラスが同じ名前のメンバを持つ場合、右側のスーパークラスにあるメンバの値が優先します。

Note:

右から左への継承でも、最も左に記述したスーパークラス (最初のスーパークラスと呼ばれることもあります) がプライマリ・スーパークラスであることは変わりません。つまり、サブクラスは最も左にあるスーパークラスからクラス・キーワード値のみを継承し、これらの値はオーバーライドされません。

例えば、クラス AB、および C から X が右から左への継承順序で継承する場合に、クラス AB からそれぞれ継承したメンバ間に競合があると、既に継承済みのメンバをクラス B のメンバでオーバーライド (置換) します。クラス AB のメンバに対するクラス C のメンバの関係も同様です。クラス X のクラス・キーワードは独占的にクラス A から継承されます。左から右への継承順序でクラス A を拡張してから B を拡張した結果と、右から左への継承順序でクラス B を拡張してから A を拡張した結果が異なるのはこのためです。いずれの定義でもキーワードは最も左のスーパークラスから継承するので、この 2 つの場合で相違が発生します。

Important:

バージョン 2010.1 より前の Caché では、継承順序が常に右から左で、変更はできませんでした。そのような古いインスタンスにあるクラスをアップグレードした場合でも、クラス・ディクショナリのアップグレードにより、自動的に右から左への継承が引き続き適用されます。したがって、バージョン 2010.1 以降、新しいクラスでは左から右への継承を既定で使用しますが、既存のコードを変更する必要はありません。

追加のトピック

登録オブジェクトを使用した作業” の章の “%ClassName() および最も適切なタイプのクラス (MSTC)” も参照してください。

コンパイラ・キーワードの概要

クラスの定義法:基本” に示したように、クラス定義またはクラス・メンバの定義にキーワードを含めることができます。クラス属性とも呼ばれる、これらのキーワードは、一般にコンパイラに影響を与えます。このセクションでは、一般的なキーワードと、それらのキーワードを Caché が提供する方法について説明します。

以下の例では、クラス定義と一般的に使用されるキーワードを示しています。

/// This sample persistent class represents a person.
Class MyApp.Person Extends %Persistent [ SqlTableName = MyAppPerson ]
{

/// Define a unique index for the SSN property.
Index SSNKey On SSN [ Unique ];

/// Name of the person.
Property Name As %String [ Required ];

/// Person's Social Security number.
Property SSN As %String(PATTERN = "3N1""-""2N1""-""4N") [ Required ];

}

この例では、以下のキーワードを示しています。

  • クラス定義では、Extends キーワードがこのクラスの継承元のスーパークラスを指定します。

    別の方法でクラスを表示すると、Extends キーワードの名前が異なるので注意が必要です。次のセクションを参照してください。

  • クラス定義では、SqlTableName キーワードは、既定の名前が使用されない場合に関連付けられたテーブルの名前を決定します。このキーワードは永続クラスに対してのみ意味があります (このドキュメントで後述します)。

  • インデックス定義では、Unique キーワードにより、Caché はインデックスが基にしたプロパティ (この例では SSN) に対して一意性を強制します。

  • 2 つのプロパティでは、Required キーワードにより、Caché はプロパティに NULL 以外の値を要求します。

PATTERN はキーワードでなく、プロパティ・パラメータです。PATTERN は角括弧ではなく括弧で囲まれる点に注意してください。

このドキュメントの後続の各章では、数多くの追加のキーワードについて説明しています。ただし、すべてのキーワードを説明しているわけではありません。ストレージに関連するキーワードは別として (これは、ほとんどドキュメント化されていません)、キーワードの詳細は "Caché クラス定義リファレンス" で調べられます。通常の編集モードでクラスを表示すると、このリファレンス情報には、適用される構文の用例が示されます。

キーワードおよび値の表示

例外はありますが、多くの場合、クラス定義またはクラス・メンバにキーワードを指定するときには、以下に示すいずれかの形式の 1 つの要素をクラスまたはクラス・メンバに追加します。

  • [ keyword ]

    キーワードを True に指定します。

  • [ Not keyword ]

    キーワードを False に指定します。

  • [ keyword=value ]

    キーワードを指定された値に指定します。

スタジオ・インスペクタでは、コンパイラ・キーワードとそれらの値は、異なる方法で表示されます。例えば、以下のクラス定義について考えてみます。

/// This sample persistent class represents a person.
/// <p>Maintenance note: This class is used by some of the bindings samples.
Class Sample.Person Extends (%Persistent, %Populate, %XML.Adaptor)
{

...

このクラスの場合、スタジオ・インスペクタは以下に示すキーワードのテーブルを表示します。

generated description: studio inspector

Name と Description は、どちらもキーワードであることに注目してください。インスペクタで Description を編集すると、スタジオによりクラス定義のコメントが更新されます (その逆も同じになります)。同様に、このクラスのスーパークラスを指定する、Super というキーワードがあります。これを編集すると、スタジオによりクラス定義の Extends 部分が更新されます。

スタジオ・インスペクタは、クラス・メンバを表示したときにも同様に動作します。この場合、インスペクタ・ウィンドウには、現在選択しているメンバについて、すべてのメンバ・キーワードと、そのキーワードの値が表示されます。(プロパティについては、インスペクタ・ウィンドウに、使用可能なプロパティ・パラメータと、そのパラメータの現在の値もリストされます。)

クラス定義を XML にエクスポートすると、エクスポートされたファイルは以下のようになります。

<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2015.1 (Build 416U)" ts="2014-12-19 15:27:27">
<Class name="Sample.Person">
<Description>
This sample persistent class represents a person.
<p>Maintenance note: This class is used by some of the bindings samples.</Description>
<Super>%Persistent,%Populate,%XML.Adaptor</Super>
<TimeChanged>63540,49568.139638</TimeChanged>
<TimeCreated>59269,38836.623</TimeCreated>
 
<Parameter name="EXTENTQUERYSPEC">
<Default>Name,SSN,Home.City,Home.State</Default>
</Parameter>
 
...

このファイルのほとんどの XML 要素は、コンパイラ・キーワードに対応します。

プログラムを使用してクラス定義にアクセスする場合、クラス定義のインスタンスにはキーワードに対応するプロパティが含まれます。プログラムを使用したクラス定義へのアクセスについては、“%Dictionary クラスの使用” の章を参照してください。

クラス・ドキュメントの作成

Caché には、インターシステムズ・クラス・リファレンス という Web ページが用意されています。このページには、インターシステムズが提供しているクラスと、ユーザが作成するクラスについて、自動的に生成されるリファレンス情報が表示されます。クラス・リファレンスは %CSP.DocumaticOpens in a new tab クラスによって生成されるため、非公式には Documatic とも呼ばれています。

このセクションではクラス・リファレンスについて紹介し、ドキュメンテーションを作成する方法および HTML マークアップを含める方法について説明します。

クラスリファレンスの概要

クラスリファレンスの目的は、クラスの使用可能な部分と、その部分の使用方法をプログラマに公表することです。以下に例を示します。

generated description: classref ex

このリファレンス情報には、クラス・メンバの定義が示されていますが、それらの実際の実装ではありません。例えば、メソッド・シグニチャが示されていますが、それらの内部定義ではありません。これには、要素間のリンクが含まれており、コードのロジックをすばやく、場合によってスタジオよりも迅速にたどることができます。また、検索オプションも用意されています。

クラス・リファレンスに含めるドキュメントの作成

クラス・リファレンスに含めるドキュメントを作成するには、クラス定義内にコメントを作成します。コメントは、/// で開始します。このようなコメントの付いたクラス宣言を前に置くと、そのコメントはクラスのページの最上位に示されます。このようなコメントの付いた特定のクラス・メンバを前に置くと、コメントは生成されたそのクラス・メンバの情報の後に示されます。クラスをコンパイルしておくと、次にクラス・リファレンス・ドキュメントを開いたときに、生成されたクラス・ドキュメントを表示できます。クラス・リファレンスのコメントを追加しない場合、クラスやパッケージに追加した項目は、そのクラスやパッケージの内容のリストに正しく表示されますが、それらを説明するテキストは表示されません。

スタジオ・インスペクタのウィンドウでクラスの [説明] フィールドを編集するか、専用の形式で作成した行をクラス・コードに追加することにより、スタジオで既存のクラス・リファレンスのコメントを拡張できます。クラス・リファレンスのコメントの構文規則は以下のように厳密です。

  • (すべての行を合わせた) クラス・リファレンスのコメントの長さは、システムの最大文字列長より短くする必要があります。"Caché プログラミング入門ガイド" の “長い文字列の制限” を参照してください。

  • クラス・リファレンスの中でクラスまたはクラス・メンバを説明するすべてのコメントは、そのコメントで説明している項目の宣言の直前に、連続するブロックとして記述する必要があります。

  • コメントのブロックを構成する各行の先頭には、3 つのスラッシュ (///) を記述します。

    Tip:

    既定では、この表示は、/// のすべての行のテキストをまとめ、その結果を 1 つの段落として扱うことに注意してください。HTML の改行 (<br>) を挿入できます。または、HTML フォーマット (<p>、</p> など) を使用できます。サブセクションを参照してください。

  • この 3 つのスラッシュは、行の先頭 (左端) に配置する必要があります。

  • クラス・リファレンスのコメントに空白行を入れることはできません。

  • クラス・リファレンスのコメントの最終行とそのコメントで説明している項目の宣言の間に空白行を入れることはできません。

スタジオ・ウィザードまたはスタジオ・インスペクタのウィンドウで [説明] フィールドを使用してクラス・リファレンスのコメントを追加する場合は、記述の詳細がスタジオで自動的に処理されます (長さの制限は除きます)。クラス・リファレンスのコメントをコードに直接追加する場合、特定のクラス・リファレンス構文エラーについては、スタジオから警告が発行されます。例えば、コメントと宣言の間に空白行を挿入した場合や、クラス・リファレンスのテキスト・ブロック内の行頭に置くスラッシュの数が不足している場合などです。これ以外の構文上の誤りがクラス・リファレンスのコメントにあっても、スタジオから警告は発行されません。

クラス・リファレンスのコメントには、以下のコード例に示すように、プレーン・テキストのほか、あらゆる標準 HTML 要素および少数のクラス・リファレンス専用の要素を使用できます。

/// <p>Transforms <i>Star</i> order messages for <i>ChartScript</i>. <br/>
/// Developed Nov 2004 by <b>MT Engineering Team</b>. <br/>
/// See also <class>StarADTtoChartScript</class> and
/// <class>StarMRGtoChartScript</class> </p>
/// <p>Only Orders for these Departments pass: </p>
/// <ul><li>CP</li><li>NS</li><li>URO</li><li>NIV</li></ul>
/// <p>As long as they are one of the following:</p>
/// <ol>
/// <li>New Child Order</li>
/// <li>Child Order Status Change</li>
/// <li>Order Cancellation</li>
/// </ol>
/// <p>Data Transformation sets "T" in MSH 11 for Test environment.</p>
Class MT.dt.StarORMtoChartScript
      Extends Ens.DataTransformDTL [ ProcedureBlock ]

{
  // The data transformation class code goes here.
}

上述の例からこのクラスのクラス・リファレンスのエントリは次のように構成されます。

generated description: documatic html

クラス・ドキュメントでの HTML マークアップの使用

クラスのコメントでは、HTML タグを使用できます。使用可能な HTML 要素は、XHTML などの HTML 標準にできる限り厳密に従って記述します。そうすることにより、あらゆるブラウザでコメントを確実に表示できます。標準的な HTML の他に、CLASS、METHOD、PROPERTY、PARAMETER、QUERY、および EXAMPLE の各タグも使用できます。(標準的な HTML タグと同様に、これらのタグの名前は大文字と小文字を区別しません。)最も一般的に使用するタグについては、ここで説明されています。その他の詳細は、%CSP.DocumaticOpens in a new tab のドキュメントを参照してください。

CLASS

クラス名をタグ付けします。クラスが存在する場合、コンテンツはクラスのドキュメントに対するリンクとして表示されます。例えば、以下のように表示されます。

/// This uses the <CLASS>Sample.Person</CLASS> class.

EXAMPLE

プログラム例をタグ付けします。このタグは、テキストの外観に影響します。それぞれの /// 行は、例の中で独立した行になります (行が単一の段落に結合される通常の場合とは対照的です)。例えば、以下のようになります。

/// <EXAMPLE>
/// set o=..%New()
/// set o.MyProperty=42
/// set o.OtherProp="abc"
/// do o.WriteSummary()
/// </EXAMPLE>

METHOD

メソッド名をタグ付けします。メソッドが存在する場合、コンテンツはメソッドのドキュメントに対するリンクとして表示されます。例えば、以下のようになります。

/// This is identical to the <METHOD>Unique</METHOD> method.

PROPERTY

プロパティ名をタグ付けします。プロパティが存在する場合、コンテンツはプロパティのドキュメントに対するリンクとして表示されます。例えば、以下のようになります。

/// This uses the value of the <PROPERTY>State</PROPERTY> property.

これは、HTML マークアップを使用した複数行にわたる説明です。

/// The <METHOD>Factorial</METHOD> method returns the factorial
/// of the value specified by <VAR>x</VAR>.

クラスのコンパイル

Caché クラス定義は、クラス・コンパイラでアプリケーションのルーチンにコンパイルされます。クラスは、コンパイルされるまでアプリケーションでは使用できません。

クラス・コンパイラは、C++ や Java など他のプログラミング言語で使用できるコンパイラとは、2 つの点で大きく異なります。第 1 に、コンパイルの結果は、ファイル・システムではなく、共有リポジトリ (データベース) に保存されます。第 2 に、コンパイラは永続クラスに対するサポートを提供します。

特に、クラス・コンパイラは以下のことを行います。

  1. 依存関係のリストを生成します。最初にコンパイルされる必要があるクラスのリストです。使用されているコンパイル・オプションによっては、最後のコンパイル以降に変更された依存関係もコンパイルされます。

  2. 継承を決定します。いずれのメソッド、プロパティ、および他のクラス・メンバが、スーパークラスから継承されるかを決定します。この継承情報を、後で参照するためにクラス・ディクショナリに保存します。

  3. 永続クラスとシリアル・クラスでは、データベース内のオブジェクトを保存するのに必要なストレージ構造を決定し、クラスの SQL 表現に必要な実行時情報を作成します。

  4. クラスで定義 (または継承) されているすべてのメソッド・ジェネレータを実行します。

  5. クラスに対する実行時コードを含む、1 つまたは複数のルーチンを生成します。クラス・コンパイラは、言語 (ObjectScript と Basic) に応じてメソッドをグループ化し、別個のルーチンを生成します。各ルーチンには、その言語のメソッドが含まれます。

    クラス・コンパイラで [生成されたソース・コードを保存] オプションを指定する場合、スタジオの ([ビュー] メニューから) [他のコードの表示] コマンドを使用して、ルーチンのソースを表示できます。

  6. 生成されたすべてのルーチンを実行可能なコードにコンパイルします。

  7. クラス記述子を作成します。これは、(ルーチンとして保存された) 特別なデータ構造で、クラスのサポートに必要な実行時のすべてのディスパッチ情報 (プロパティの名前、メソッドの位置など) を含みます。

クラス・コンパイラの呼び出し

クラス・コンパイラを呼び出す方法は、複数あります。

  • スタジオの [ビルド] メニューを使用する方法

  • Caché コマンド行 (ターミナル) で、%SYSTEM.OBJOpens in a new tab オブジェクトの Compile() メソッドを使用する方法

     Do $System.OBJ.Compile("MyApp.MyClass")

テーブルを作成するために SQL DDL 文を使用した場合、そのテーブルに対応する永続クラスをコンパイルするために、クラス・コンパイラが自動的に呼び出されます。

クラス・コンパイラに関する留意事項

コンパイルの順序

クラスのコンパイル時、コンパイルしているクラスに依存関係に関する情報が含まれている場合は、Caché により、その他のクラスもリコンパイルされます。例えば、システムは、クラスに含まれるすべてのサブクラスをコンパイルします。場合によっては、クラスのコンパイル順序を制御することが必要になります。そのためには、SystemDependsOn、および CompileAfter キーワードを使用します。詳細は、"Caché クラス定義リファレンス" を参照してください。

特定のクラスをコンパイルするときに、コンパイラによってリコンパイルされることになるクラスを調べるには、$SYSTEM.OBJ.GetDependencies() メソッドを使用します。以下に例を示します。

SAMPLES>d $system.OBJ.GetDependencies("Sample.Address",.included)
 
SAMPLES>zw included
included("SOAP.Demo.LookupCity")=""
included("SOAP.DemoProxy.LookupCity")=""
included("Sample.Address")=""
included("Sample.Customer")=""
included("Sample.Employee")=""
included("Sample.Person")=""
included("Sample.Vendor")=""

このメソッドのシグニチャは、以下のとおりです。

classmethod GetDependencies(ByRef class As %String, Output included As %String, qspec As %String) as %Status

以下はその説明です。

  • class は、1 つのクラス名 (この例の場合)、クラス名のコンマ区切りリスト、またはクラス名の多次元配列になります。(多次元配列の場合、この引数は必ず参照で渡してください。)ワイルドカードを含めることもできます。

  • included は、class がコンパイルされるときに、コンパイルされることになるクラスの名前の多次元配列です。

  • qspec は、コンパイラのフラグと修飾子の文字列です。次のサブセクションを参照してください。これを省略すると、このメソッドは、現在のコンパイラのフラグと修飾子を考慮するようになります。

クラス・コンパイラのフラグおよび修飾子の表示

Compile() メソッドでは、結果に影響を与えるフラグおよび修飾子を指定することもできます。修飾子およびフラグの引数リストでの位置は、Compile() メソッドの説明で示しています。該当のフラグを表示するには、以下のコマンドを実行します。

 Do $System.OBJ.ShowFlags()

これによって、以下のような出力が生成されます。

    b - Include sub classes.
    c - Compile. Compile the class definition(s) after loading.
    d - Display. This flag is set by default.
    e - Delete extent.
    h - Generate help.
    i - Validate XML export format against schema on Load.
    k - Keep source.  When this flag is set, source code of
        generated routines will be kept.
    l - Lock classes while compiling.  This flag is set by default.
    p - Percent.  Include classes with names of the form %*.
    r - Recursive.  Compile all the classes that are dependency predecessors.
    s - Process system messages or application messages.
    u - Update only.  Skip compilation of classes that are already up-to-date.
    y - Include classes that are related to the current class in the way that
        they either reference to or are referenced by the current class in SQL usage.

These flags are deprecated a, f, g, o, q, v
Default flags for this namespace =dil
You may change the default flags with the SetFlags(flags,system) classmethod.

すべての修飾子のリストを、修飾子の説明、タイプ、および関連する値と共に表示するには、以下のコマンドを実行します。

 Do $System.OBJ.ShowQualifiers()

修飾子の情報は、以下のいずれかと同様の形式で表示されます。

            Name: /checkschema
    Description: Validate imported XML files against the schema definition.
           Type: logical
           Flag: i
  Default Value: 1

           Name: /checksysutd
    Description: Check system classes for up-to-dateness
           Type: logical
  Default Value: 0

           Name: /checkuptodate
    Description: Skip classes or expanded classes that are up-to-date.
           Type: enum
           Flag: ll
      Enum List: none,all,expandedonly,0,1
  Default Value: expandedonly
  Present Value: all
  Negated Value: none

ビットマップ・インデックスを含むクラスのコンパイル

ビットマップ・インデックスを含むクラスをコンパイルする場合、そのクラスに対するビットマップ・エクステント・インデックスが定義されていないと、クラス・コンパイラはビットマップ・エクステント・インデックスを生成します。プロダクション・システムのクラスにビットマップ・インデックスを追加するときには特別な注意が必要です。詳細は、"Caché SQL 最適化ガイド" の “インデックスの定義と構築” の章にある “ビットマップ・エクステント・インデックスの生成” のセクションを参照してください。

メモリにクラスの既存のインスタンスが存在する場合のコンパイル

コンパイル対象のクラスのインスタンスが開いているときにコンパイラを呼び出しても、エラーは発行されません。既に開いているインスタンスでは、その既存のコードが引き続き使用されます。コンパイル後に開いた別のインスタンスでは、新しくコンパイルしたコードが使用されます

クラスを配置済みにする方法

いくつかの独自のクラスを顧客に送信する前に配置済みにすることもできます。この処理によって、ソース・コードが表示されなくなります。

クラス定義に、顧客には見せたくないメソッド定義が含まれている場合は、そのクラスをコンパイルしてから、$SYSTEM.OBJ.MakeClassDeployed() を使用します。例えば、以下のようになります。

 d $system.OBJ.MakeClassDeployed("MyApp.MyClass")

代替手段については、"顧客のデータベースへのコンパイル済みコードの追加" の記事を参照してください。

配置モードについて

クラスが配置モードになると、そのクラスのメソッド定義とトリガ定義は削除されます。(クラスがデータ型クラスである場合、クエリ・キャッシュによって実行時にメソッド定義が必要になる可能性があるために、メソッド定義が保持されることに注意してください。)

スタジオではクラス定義を開くことはできますが、読み取り専用になります。

配置済みのクラスは、エクスポートやコンパイルができません。ただし、そのクラスのサブクラスのコンパイルは可能です (配置されてない場合)。

クラスの配置を元に戻す手段はありません。ただし、前もって定義をエクスポートしておくと、ファイルからその定義をインポートして、クラスを置き換えることができます。(これは、独自のクラスのいずれかを誤って不完全に配置モードにしてしまった場合に役立ちます。)

FeedbackOpens in a new tab