Caché オブジェクトは “パッケージ” をサポートしています。パッケージとは、関連するクラスを特定のネームスペース内にグループとしてまとめる方法です。パッケージには、以下の利点があります。
パッケージの概要
パッケージは、関連するクラスを共通の名前の下に 1 つのグループとしてまとめる簡単な方法です。例えば、アプリケーションに “Accounting” システムと “Inventory” システムがあるとします。これらのアプリケーションを構成するクラスを、“Accounting” パッケージと “Inventory” パッケージに編成することができます。
クラス・パッケージ
上記のクラスは、いずれも (パッケージ + クラス名からなる) フルネームを使用して参照されます。
 Do ##class(Accounting.Invoice).Method()
 Do ##class(Inventory.Item).Method()
パッケージ名が、コンテキストから決定される場合は (下記参照)、パッケージ名を省略することができます。
 Do ##class(Invoice).Method()
パッケージは、単純に名前付け規約です。つまり、パッケージはクラスの命名方法を提供するだけで、それ以上の基本機能を提供するものではありません。
クラスと同様に、パッケージ定義は、Caché ネームスペース内に存在します。パッケージは、複数のネームスペースにまたがることができません。将来的には、サブスクリプト・レベル・マッピングの使用により、他のネームスペース内のパッケージを参照できるようになる予定です。
パッケージ名
パッケージ名は、単純に文字列です。 “.” (ピリオド) を含むことがありますが、その他の句読点は含まれません。パッケージには “.” が含まれますが、パッケージの階層はありません (さまざまな Caché 開発ツールは、利便性のためにパッケージを階層として表示します)。あるクラスに “Test.Subtest.TestClass” と名前を付けた場合、クラス名が “TestClass” で、パッケージ名が “Test.Subtest” になります (以下で説明されるように、SQLはスキーマ “Test_TestClass” にマッピングされます)。
パッケージ名の長さと使用法には、以下のような制限があります。
パッケージの定義
パッケージは、暗にクラス名の意味を含みます。パッケージを作成するには、(Caché スタジオ で) 新規クラス・ウィザードを使用する方法が簡単です。このウィザードには、新しいパッケージ名を入力できるボックスがあります (現在のパッケージのリストから、表示させることもできます)。
パッケージ内のクラスをすべて削除すると、そのパッケージも自動的に削除されます。
もう 1 つの方法は、単純にクラスを作成する方法です。この場合、パッケージは自動的に定義されます。例えば、定義内でクラス名にパッケージ名を追加すると、パッケージを定義することができます。
Class Accounting.Invoice {
}
これは、“Accounting” パッケージ内の Invoice というクラスを定義します。
Caché スタジオ で、ワークスペース・ウィンドウの [プロジェクト] タブ内のパッケージ名を右クリックすると、パッケージの追加の特性 (説明など) を表示したり、編集できます。
パッケージの使用
クラス名の使用には、2 つの方法があります。
完全修飾名の使用方法は簡単です。
 // 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 指示文によって、特定のクラスに対して、検索するパッケージを指定します。例えば、以下の通りです。
#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 文を指定すると、パッケージ名 User は自動的にはインポートされません。そのため、必要であれば、以下のように指定する必要があります。
#import MyPackage
#import User
このような論理である理由は、User をインポートしたくない場合があるからです。#IMPORT 文を利用して、興味深いトリックが使用できます。
#import Customer1
 Do ##class(Application).Run()
App.MAC を以下のように変更します。
#import Customer2
 Do ##class(Application).Run()
App.MAC をリコンパイルするとき、“Customer2” パッケージに対する Application クラスを使用します。このようなトリックを使用する場合は、事前に計画することが必要です。コード互換性だけでなく、ストレージ構造への影響も考慮する必要があります。
パッケージと SQL
すべてのパッケージは、SQL スキーマに対応しています。例えば、クラスが Team.Player (“Team” パッケージの Player クラス) である場合、対応するテーブルは “Team.Player” (“Team” スキーマの Player テーブル) です。
既定のパッケージは “User” で、“SQLUser” スキーマに対応しています。したがって、User.Person という名前のクラスは、SQLUser.Person という名前のテーブルに対応します。
パッケージ名にピリオドが含まれる場合、ピリオドの代わりにアンダースコア (_) を使用します。例えば、MyTest.Test.MyClass クラス (“MyTest.Test” パッケージの MyClass クラス) は、MyTest_Test.MyClass テーブル (“MyTest_Test” スキーマの MyClass テーブル) になります。
SQL テーブル名がスキーマ名なしで参照される場合、既定のスキーマ名 (SQLUser) が使用されます。例えば、以下のコマンド
Select ID, Name from Person
は、以下と同じです。
Select ID, Name from SQLUser.Person
ビルトイン・パッケージ
旧バージョンとの互換性により、2 つの "ビルトイン" パッケージがあります。