Caché オブジェクトは
パッケージ をサポートしています。パッケージとは、関連するクラスを特定のネームスペース内にグループとしてまとめる方法です。パッケージには、以下の利点があります。
-
大規模なアプリケーションを構築し、他の開発者とコードを共有する簡単な方法を開発者に提供します。
-
クラス間で名前が衝突する問題を容易に回避できます。
-
オブジェクト・ディクショナリ内の SQL スキーマを、単純明解に表現する論理的な方法を提供します。1 つのパッケージが 1 つのスキーマに対応します。
クラス・パッケージ
上記のクラスは、いずれも (パッケージ + クラス名からなる) フルネームを使用して参照されます。
Do ##class(Accounting.Invoice).Method()
Do ##class(Inventory.Item).Method()
パッケージ名が、コンテキストから決定される場合は (下記参照)、パッケージ名を省略することができます。
Do ##class(Invoice).Method()
パッケージは、単純に名前付け規約です。つまり、パッケージはクラスの命名方法を提供するだけで、それ以上の基本機能を提供するものではありません。
クラスと同様に、パッケージ定義は、Caché ネームスペース内に存在します。パッケージは、複数のネームスペースにまたがることができません。将来的には、サブスクリプト・レベル・マッピングの使用により、他のネームスペース内のパッケージを参照できるようになる予定です。
パッケージ名の長さと使用法には、以下のような制限があります。
-
パッケージ名 (
. も含む) は、31 文字以下に制限されています。
-
ネームスペース内では、各パッケージ名は一意でなければなりません (大文字、小文字関係なく)。
-
パッケージ内で、各クラス名は最初の 25 文字内で一意でなければなりません。
パッケージは、暗にクラス名の意味を含みます。パッケージを作成するには、(
Caché スタジオ で) 新規クラス・ウィザードを使用する方法が簡単です。このウィザードには、新しいパッケージ名を入力できるボックスがあります (現在のパッケージのリストから、表示させることもできます)。
パッケージ内のクラスをすべて削除すると、そのパッケージも自動的に削除されます。
もう 1 つの方法は、単純にクラスを作成する方法です。この場合、パッケージは自動的に定義されます。例えば、定義内でクラス名にパッケージ名を追加すると、パッケージを定義することができます。
Class Accounting.Invoice {
}
Caché スタジオ で、ワークスペース・ウィンドウの [プロジェクト] タブ内のパッケージ名を右クリックすると、パッケージの追加の特性 (説明など) を表示したり、編集できます。
-
完全修飾名を使用する方法 (例: Package.Class)
-
短いクラス名だけを使用し、クラス・コンパイラにクラスがいずれのパッケージに属するのかを解決させる方法。
// create an instance of Lab.Patient
Set patient = ##class(Lab.Patient).%New()
コンパイラに名前を解決させるには、.MAC コード、あるいはクラス定義内で #IMPORT 指示文が必要です。import が指定されていない場合、
短い クラス名は、
User あるいは
%Library パッケージにあるものとみなされます。
// create an instance of Person
Set person = ##class(Person).%New()
// this is the same as:
Set person = ##class(User.Person).%New()
#IMPORT 指示文によって、特定のクラスに対して、検索するパッケージを指定します。例えば、以下の通りです。
#import Lab
// Look for "Patient" within Lab package.
Set patient = ##class(Patient).%New()
1 つの MAC ルーチン内に、複数の #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 文の順序は問いません。不明確なショート・クラス名を使用するとエラーになります。つまり、2 つ以上のパッケージのクラス名が同じで、そのパッケージすべてをインポートする場合、コンパイラがパッケージ名を解決する時点でエラーになります。このようなエラーを避けるためにフル・ネームを使用してください。
クラス・キーワードの IMPORT は、同じ方法で動作します。クラス定義内のクラス・リファレンスの解決に、いずれのパッケージを使用するかを指定します。また、#IMPORT 文を、生成されたコードに配置することも指定します。#IMPORT 文がない場合は、以下のように指定したものと同じことになります。
一度、#IMPORT 文を指定すると、パッケージ名 User は自動的にはインポートされません。そのため、必要であれば、以下のように指定する必要があります。
#import MyPackage
#import User
このような論理である理由は、User をインポートしたくない場合があるからです。#IMPORT 文を利用して、興味深いトリックが使用できます。
#import Customer1
Do ##class(Application).Run()
#import Customer2
Do ##class(Application).Run()
App.MAC をリコンパイルするとき、
Customer2 パッケージに対する
Application クラスを使用します。このようなトリックを使用する場合は、事前に計画することが必要です。コード互換性だけでなく、ストレージ構造への影響も考慮する必要があります。
SQL テーブル名がスキーマ名なしで参照される場合、既定のスキーマ名 (SQLUser) が使用されます。例えば、以下のコマンド
Select ID, Name from Person
Select ID, Name from SQLUser.Person
旧バージョンとの互換性により、2 つの "ビルトイン" パッケージがあります。