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?

パッケージのオプション

この章では、パッケージについて詳しく説明します。項目は以下のとおりです。

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

永続クラスの場合は、パッケージが SQL スキーマとして SQL で表現されます。詳細は、このドキュメントで後述する “パッケージからスキーマへのプロジェクション” を参照してください。

Important:

パッケージ名が含まれていないクラスへの参照を Caché が検出したときに、クラス名の先頭が “%” の場合、Caché は、そのクラスが “%Library” パッケージに含まれているものと見なします。

パッケージの概要

Caché は、特定のデータベース内の関連するクラスをグループ化する、パッケージをサポートしています。パッケージには、以下の利点があります。

  • 大規模なアプリケーションを構築し、他の開発者とコードを共有する簡単な方法を開発者に提供します。

  • クラス間で名前が衝突する問題を容易に回避できます。

  • オブジェクト・ディクショナリ内の SQL スキーマを、単純明解に表現する論理的な方法を提供します。つまり、1 つのパッケージが 1 つのスキーマに対応します。

パッケージは、関連するクラスを共通の名前の下に 1 つのグループとしてまとめる簡単な方法です。例えば、アプリケーションに “Accounting” システムと “Inventory” システムがあるとします。これらのアプリケーションを構成するクラスを、“Accounting” パッケージと “Inventory” パッケージに編成できます。

generated description: package1.jpg

上記のクラスは、いずれも (パッケージ + クラス名から成る) フル・ネームを使用して参照されます。

 Do ##class(Accounting.Invoice).Method()
 Do ##class(Inventory.Item).Method()

パッケージ名がコンテキストから決定される場合は (下記参照)、パッケージ名を省略できます。

 Do ##class(Invoice).Method()

クラスと同様に、パッケージ定義は、Caché データベース内に存在します。パッケージのデータベースからネームスペースへのマッピングの詳細は、“パッケージ・マッピング” のセクションを参照してください。

パッケージ名

パッケージ名は、文字列です。“.” (ピリオド) は使用できますが、その他の句読点は使用できません。パッケージ名のピリオドで区切られた各部は、1 つのサブパッケージであり、複数のサブパッケージが存在することもあります。あるクラスに Test.Subtest.TestClass と名前を付けた場合、パッケージ名は Test、サブパッケージ名は Subtest、クラス名は TestClass になります。

パッケージ名の長さと使用法には、以下のような制限があります。

  • パッケージ名は長さ制限に従います。"Caché プログラミング入門ガイド" の "識別子のルールとガイドライン" にある “クラス” を参照してください。

  • 1 つのネームスペース内では、各パッケージ名が一意になる必要があります (大文字と小文字は区別されません)。つまり、1 つのネームスペース内に “ABC” と “abc” というパッケージが同時に存在することはなく、“abc.def” というパッケージとサブパッケージは、“ABC” パッケージの一部として扱われるということです。

識別子に関する一般的な情報は、“クラスの定義とコンパイル” の章の “名前付け規約” を参照してください。

パッケージの定義

パッケージは、暗にクラス名の意味を含みます。クラスを作成すると、パッケージは自動的に定義されます。同様に、パッケージ内のクラスをすべて削除すると、そのパッケージも自動的に削除されます。

以下に、パッケージ名が Accounting でクラス名が Invoice、完全修飾クラス名が Accounting.Invoice の例を示します。

Class Accounting.Invoice 
{
}

パッケージ・マッピング

定義では、各パッケージは、特定のデータベースに含まれます。しばしば、各データベースは、ネームスペースに関連付けられ、データベースとネームスペースは、共通の名前を共有します。これは、SAMPLESUSER のように、さまざまなシステム提供のデータベースとネームスペースに該当します。データベース内のパッケージ定義をそのデータベースと関連付けられていないネームスペースで使用できるようにするには、パッケージ・マッピングを使用します。この手順については "Caché システム管理者ガイド" で詳しく説名していますが、以下に概要を示します。パッケージを格納しているデータベースがソース・データベースです。パッケージのマッピング先のネームスペースはターゲット・ネームスペースと呼びます。パッケージをマップする手順は以下のとおりです。

  1. 管理ポータルのホーム・ページで、[ネームスペース] ページ (システム, 構成, ネームスペース) に移動します。

  2. [ネームスペース] ページで、テーブル内の対応する行にある [パッケージ・マッピング] をクリックして、ターゲット・ネームスペースを選択します。ターゲット・ネームスペースの [パッケージ・マッピング] ページが表示されます。

  3. [パッケージ・マッピング] ページで、[新規パッケージ・マッピング] をクリックします。これによって、マッピング設定のダイアログが表示されます。

  4. このダイアログで、以下のようにフィールドに情報を入力します。

    • [パッケージ・データベースの場所] — ソース・データベース。

    • [パッケージ名] — マップするパッケージ。まだ作成していないパッケージをマップする場合、[新規パッケージ] をクリックしてパッケージ名を入力することにより、事前にその名前を指定できます。

    [OK] をクリックするとこれらの値が使用され、ダイアログが閉じます。

  5. [パッケージ・マッピング] ページにマッピングが表示されます。[変更を保存] をクリックし、マッピングを保存します。

パッケージをネームスペースを超えてマップすると、パッケージの定義はマップされますが、そのデータはマップされません。したがって、SAMPLES ネームスペースの Sample パッケージを USER ネームスペースにマップしても、SAMPLES ネームスペースの Sample.PersonOpens in a new tab のインスタンスが USER ネームスペースで使用できるようにはなりません。

Important:

パッケージをマップするときには、そのパッケージ内のクラスが必要とするすべてのコードとデータを特定して、そのすべてのコードとデータがすべてのターゲット・ネームスペースで使用できることを必ず確認します。マップされるクラスは、以下の項目に依存している可能性があります。

  • インクルード・ファイル

  • ルーチン

  • その他のクラス

  • テーブル

  • グローバル

追加のルーチン、パッケージ、およびグローバル・マッピングを必要に応じて使用して、これらの項目がターゲット・ネームスペースで使用できるようにします。"Caché システム管理者ガイド"" の “Caché の構成” の章にある “ネームスペースへのグローバル、ルーチン、およびパッケージ・マッピングの追加” を参照してください。

パッケージをマップすると、そのパッケージのクラス定義、同じパッケージ内の生成されたルーチンにマッピングが適用されます。

複数のネームスペースにわたるパッケージのマッピング

Caché は、1 つの動作で複数のターゲット・ネームスペースにわたって同じソース・パッケージを使用できるようにする機能を備えています。このようなマッピングにより、DOCBOOKSAMPLES を除くすべてのネームスペースでパッケージが使用できるようになります。

パッケージを複数のネームスペースで使用可能にする手順は以下のとおりです。

  1. "Caché システム管理ガイド" の “Caché の構成” の章にある “ネームスペースの作成” の説明に従い、%ALL というネームスペースを作成します。

  2. このセクションの説明に従ってパッケージのマッピングを作成し、保存します。

マッピングしたパッケージのクラスが、%SYS ネームスペース、USER ネームスペース、および任意のユーザ定義ネームスペースで認識でき、使用可能になります。

Note:

%ALL ネームスペースを削除すると、そのマッピングが削除されます。

クラス参照時のパッケージの使用

クラスの参照には、2 つの方法があります。

  • 完全修飾された名前 (すなわち、Package.Class) を使用します。例えば、以下のようになります。

     // create an instance of Lab.Patient
     Set patient = ##class(Lab.Patient).%New()
  • 短いクラス名を使用し、クラスがいずれのパッケージに属するのかをクラス・コンパイラに解決させます。

    既定では、短いクラス名を使用すると、Caché はそのクラスを、使用しているコードを含むクラスのパッケージ (存在する場合)、%Library パッケージ、または User パッケージのいずれかに含まれるクラスであると見なします。

    コンパイラで別のパッケージのクラスを検索する場合は、次のセクションで説明するように、それらのパッケージをインポートします。

    Note:

    不明確な短いクラス名を使用するとエラーになります。つまり、2 つ以上のパッケージに同じ短いクラス名が付いていて、そのパッケージすべてをインポートする場合、コンパイラがパッケージ名を解決する時点でエラーになります。このようなエラーを避けるためにフル・ネームを使用してください。

パッケージのインポート

パッケージをインポートするときに、Caché はインポートするパッケージ内で短いクラス名を検索します。クラス定義では、クラスの 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.MyClassMyMethod() メソッドを定義してから、User.MyClass を継承する MyPackage.MyClass クラスを作成し、これをコンパイルするとします。この場合、Caché は継承した MyMethod() メソッドを MyPackage.MyClass でコンパイルしますが、このメソッドのクラス名は User.MyClass のコンテキストで解決されます (このメソッドをこのコンテキストで定義しているからです)。

パッケージのインポートのヒント

パッケージをインポートすることで、さらに柔軟性のあるコードを作成できます。例えば、以下のようなコードを作成できます。

#import Customer1
 Do ##class(Application).Run()

App.MAC を以下のように変更します。


#import Customer2
 Do ##class(Application).Run()

App.MAC をリコンパイルするときには、Customer2.Application クラスを使用します。このようなコードを作成するには計画が必要です。つまり、コードの互換性だけでなく、ストレージ構造への影響も考慮する必要があります。

FeedbackOpens in a new tab