パッケージのオプション
ここでは、パッケージについて詳しく説明します。
永続クラスの場合は、パッケージが SQL スキーマとして SQL で表現されます。詳細は、"パッケージからスキーマへのプロジェクション" を参照してください。
パッケージ名が含まれていないクラスへの参照を InterSystems IRIS® データ・プラットフォームが検出したときに、クラス名の先頭が “%” の場合、InterSystems IRIS は、そのクラスが %Library パッケージに含まれているものと見なします。
パッケージの概要
InterSystems IRIS は、特定のデータベース内の関連するクラスをグループ化するパッケージをサポートしています。パッケージには、以下の利点があります。
-
大規模なアプリケーションを構築し、他の開発者とコードを共有する簡単な方法を開発者に提供します。
-
クラス間で名前が衝突する問題を容易に回避できます。
-
オブジェクト・ディクショナリ内の SQL スキーマを、単純明快に表現する論理的な方法を提供します。つまり、1 つのパッケージが 1 つのスキーマに対応します。
パッケージは、関連するクラスを共通の名前の下に 1 つのグループとしてまとめる簡単な方法です。例えば、アプリケーションに Accounting システムと Inventory システムがあるとします。これらのアプリケーションを構成するクラスを、Accounting パッケージと Inventory パッケージに編成できます。
上記のクラスは、いずれも (パッケージ + クラス名から成る) フル・ネームを使用して参照されます。
Do ##class(Accounting.Invoice).Method()
Do ##class(Inventory.Item).Method()
パッケージ名がコンテキストから決定される場合は (下記参照)、パッケージ名を省略できます。
Do ##class(Invoice).Method()
クラスと同様に、パッケージ定義は、InterSystems IRIS データベース内に存在します。パッケージのデータベースからネームスペースへのマッピングの詳細は、"パッケージ・マッピング" を参照してください。
パッケージ名
パッケージ名は、文字列です。. (ピリオド) は使用できますが、その他の句読点は使用できません。パッケージ名のピリオドで区切られた各部は、1 つのサブパッケージであり、複数のサブパッケージが存在することもあります。あるクラスに Test.Subtest.TestClass と名前を付けた場合、パッケージ名は Test、サブパッケージ名は Subtest、クラス名は TestClass になります。
パッケージ名の長さと使用法には、以下のような制限があります。
-
パッケージ名は長さ制限に従います。"識別子のルールとガイドライン" を参照してください。
-
1 つのネームスペース内では、各パッケージ名が一意になる必要があります (大文字と小文字は区別されません)。つまり、1 つのネームスペース内に “ABC” と “abc” というパッケージが同時に存在することはなく、“abc.def” というパッケージとサブパッケージは、“ABC” パッケージの一部として扱われるということです。
詳細は、"識別子のルールとガイドライン" および "ネームスペースで何にアクセス可能か" を参照してください。
パッケージの定義
パッケージは、暗にクラス名の意味を含みます。クラスを作成すると、パッケージは自動的に定義されます。同様に、パッケージ内のクラスをすべて削除すると、そのパッケージも自動的に削除されます。
以下に、パッケージ名が Accounting でクラス名が Invoice、完全修飾クラス名が Accounting.Invoice の例を示します。
Class Accounting.Invoice
{
}
パッケージ・マッピング
定義では、各パッケージは、特定のデータベースに含まれます。しばしば、各データベースは、ネームスペースに関連付けられ、データベースとネームスペースは、共通の名前を共有します。データベース内のパッケージ定義をそのデータベースと関連付けられていないネームスペースで使用できるようにするには、パッケージ・マッピングを使用します。この手順は、"ネームスペースへのマッピングの追加" で説明されています。
パッケージをネームスペースを超えてマップすると、パッケージの定義はマップされますが、そのデータはマップされません。
クラス参照時のパッケージの使用
クラスの参照には、2 つの方法があります。
-
完全修飾された名前 (すなわち、Package.Class) を使用します。例えば、以下のようになります。
// create an instance of Lab.Patient Set patient = ##class(Lab.Patient).%New()
-
短いクラス名を使用し、クラスがいずれのパッケージに属するのかをクラス・コンパイラに解決させます。
既定では、短いクラス名を使用すると、InterSystems IRIS はそのクラスを、使用しているコードを含むクラスのパッケージ (存在する場合)、%Library パッケージ、または User パッケージのいずれかに含まれるクラスであると見なします。
コンパイラで別のパッケージのクラスを検索する場合は、それらのパッケージをインポートします。
Note:不明確な短いクラス名を使用するとエラーになります。つまり、2 つ以上のパッケージに同じ短いクラス名が付いていて、そのパッケージすべてをインポートする場合、コンパイラがパッケージ名を解決する時点でエラーになります。このようなエラーを避けるためにフル・ネームを使用してください。
パッケージのインポート
パッケージをインポートするときに、InterSystems IRIS はインポートするパッケージ内で短いクラス名を検索します。クラス定義では、クラスの Import 指示文または ObjectScript の #IMPORT 指示文を使用してパッケージをインポートできます。このセクションでは、これらの指示文について説明し、User パッケージに対する影響と、サブクラスに対する影響について述べ、いくつかのヒントも紹介します。
クラスの Import 指示文
クラス定義の最上位 (Class 行の前) に、クラスの Import 指示文を含めることができます。この指示文の構文は、以下のようになります。
Import packages
Class name {}
packages は、単一のパッケージ、または括弧で囲んだ複数のパッケージのコンマ区切りリストのいずれかにします。Import は大文字と小文字を区別しませんが、ここに示すように、通常は最初の文字を大文字にします。
クラス・コンテキストでは、現在のパッケージが常に暗黙的にインポートされます。
ObjectScript の #IMPORT 指示文
ObjectScript メソッドでは、#IMPORT 指示文でパッケージをインポートし、短いクラス名を使用して、パッケージ内のクラスを参照できます。この指示文の構文は、以下のようになります。
#import packagename
packagename はパッケージの名前です。#import は大文字と小文字が区別されません。例えば、以下のようになります。
#import Lab
// Next line will use %New method of Lab.Patient, if that exists
Set patient = ##class(Patient).%New()
#IMPORT 指示文は複数使用できます。
#import Lab
#import Accounting
// Look for "Patient" within Lab & Accounting packages.
Set pat = ##class(Patient).%New()
// Look for "Invoice" within Lab & Accounting packages.
Set inv = ##class(Invoice).%New()
#IMPORT 指示文の順序は、コンパイラが短いクラス名を解決する方法に影響しません。
明示的なパッケージのインポートによる User パッケージへのアクセスに対する影響
コードによって明示的にパッケージをインポートすると、User パッケージは自動的にインポートされません。そのパッケージが必要な場合は、パッケージも明示的にインポートする必要があります。例えば、以下のようになります。
#import MyPackage
#import User
このような論理である理由は、User パッケージをインポートしたくない場合があるからです。
パッケージのインポートおよび継承
クラスはスーパークラスから明示的にインポートされたパッケージを継承します。
クラスの名前は、現在のクラス名ではなく、その名前が最初に使用されたコンテキストで解決されます。例えば、User.MyClass で MyMethod() メソッドを定義してから、User.MyClass を継承する MyPackage.MyClass クラスを作成し、これをコンパイルするとします。この場合、InterSystems IRIS は継承した MyMethod() メソッドを MyPackage.MyClass でコンパイルしますが、このメソッドのクラス名は User.MyClass のコンテキストで解決されます (このメソッドをこのコンテキストで定義しているからです)。
パッケージのインポートのヒント
パッケージをインポートすることで、さらに柔軟性のあるコードを作成できます。例えば、以下のようなコードを作成できます。
#import Customer1
Do ##class(Application).Run()
App.MAC を以下のように変更します。
#import Customer2
Do ##class(Application).Run()
App.MAC をリコンパイルするときには、Customer2.Application クラスを使用します。このようなコードを作成するには計画が必要です。つまり、コードの互換性だけでなく、ストレージ構造への影響も考慮する必要があります。