Caché の今回のリリースでは、Caché オブジェクト・テクノロジーに関する複数の重要な機能が強化されています。これらの機能や、既存のオブジェクトに対する影響について、以下のセクションで説明しています。
Caché オブジェクトの今回のリリースは、旧リリースとのソース互換を持つように設計されています。しかし、クラス・コンパイラやクラス・ディクショナリ、オブジェクト・コード形式には、内部的に変更されている部分が多くあります。このため、アップグレードには、すべてのクラスのリコンパイル、およびすべてのクラス定義の内部的な変換も必要です。
Note:
v5.0 開発者キットの旧バージョンからアップグレードする場合は、ここで指定されているアップグレードの手順に従わなければなりません。
Caché の今回のバーションでは、新しい、よりコンパクトなクラス・ディクショナリ (Caché 内のクラス定義を保持するのに使用される構造) を導入しています。Caché は、クラス・ディクショナリを新しい構造に自動的にアップグレードするメソッドを提供します。
また、既存のクラス定義を外部ファイル (CDL ファイル等) にエクスポートし、新規の Caché をインストールした後にそのファイルをリロードすることもできます。次の章の
クラス定義の移行 を参照してください。
既存の Caché システムをアップグレードする場合、以下のように Caché コマンド行で Upgrade() コマンドを実行して、ネームスペース内のすべてのクラス定義をアップグレードすることができます。
このコマンドを使用して、現在のネームスペース内のすべてのクラスに対する、クラス・ディクショナリをアップグレードできます。アップグレードされたクラスは、使用前にリコンパイルする必要があります。
以下のように Caché コマンド行で CompileAll() コマンドを実行することで、ネームスペース内のすべてのクラスをリコンパイルできます。
Do $system.OBJ.CompileAll()
すべてのネームスペース内のクラス・ディクショナリをアップグレードする新規のコマンドも追加されています。
Do $system.OBJ.UpgradeAll()
Do $system.OBJ.Upgrade("c")
^%UPDATECLASSES ルーチンを使用すると、各ネームスペースのクラスをターミナルに 1 つずつ更新したり、バックグラウンドで複数のプロセスを実行することにより、すべてのネームスペースを一括で更新することができます。
$system.OBJ.Upgrade() コマンドは、ディスク上に格納されている現在のクラス定義のアップグレードを実行します。これは、クラス定義にのみ影響を与え、ユーザ・データには影響を与えません。
ダウングレード に対応する関数はありません。ダウングレードの能力を保持したい場合は、アップグレード前にクラス定義を外部ファイル (例えば、バージョン 4.x を使用している場合は CDL ファイル) にエクスポートしておきます。ダウングレードするには、保存しておいたクラス定義をリロードします。
Caché の旧バージョンのオブジェクト・アプリケーションを、新バージョンに移行する場合は、以下の手順に従います。
-
Caché の旧バージョンから、既存のクラス定義を 1 つ、または複数の CDL ファイルにエクスポートします。
-
CDL ファイル (1 つまたは複数) を新バージョンの Caché にロードします。以上の手順は、Caché スタジオや Caché エクスプローラを使用するか、または Caché コマンド行から実行することもできます。
Do $system.OBJ.Load("myfile.cdl","c")
-
Important:
コンパイラ・エラーを避けるために、コンパイルを実行する前に、
[プロセスごとの最大メモリ (KB)] の設定を最高値 (16384 KB) に更新します。この設定は、
Caché 構成マネージャの
[詳細] タブの
[プロセス] にあります。旧バージョンの Caché における既定の設定は 256 KB でした。
基本的には旧バージョンとの互換性を確保しておりますが、一部 Caché オブジェクトの旧バージョンとの互換性がない場合もあります。以下はその例です。
-
-
クラス・ディクショナリ構造の変更 クラス・ディクショナリ構造に直接アクセスするアプリケーションで問題が発生します (クラス・ディクショナリ・グローバルへ直接アクセスした場合、またはドキュメント化されていないマクロを使用した場合)。
-
クラス・コンパイラによる、継承規則の強制 クラス・コンパイラは、オーバーライドされたメソッドのシグニチャが、スーパークラスのシグニチャと適合するかを確認します。今回のバージョンでは、旧バージョンでコンパイルされたコードの一部が、コンパイルされたときに
シグニチャの不適合 エラーを取得する場合もあります。このエラーを修正するには、シグニチャ (引数や、それぞれのタイプの数) と、オーバーライドされたメソッドのシグニチャが適合していることを確認します。
-
-
-
再最適化されたオブジェクト・コード Caché 5.0では、Caché 仮想マシンの説明を表すバイト・コードは再最適化されています。 したがって、すべてのソースは新規のコードを使用するためにリコンパイルされる必要があります。バージョン 4.1 以前の Caché では、ルーチン・オブジェクト・コードは、Caché の 4.1 以降のバージョンと上位互換があるので、ユーザは以下のことを行うことができます。
-
Caché の古いバージョンを使用した
.INT や
.MAC ルーチンのコンパイル
-
%RIMF ユーティリティを使用した、4.1 以降のバージョンでのオブジェクト・コードのロード
Caché 5.0 は、Caché の従来のバージョンとは異なります。Caché 5.0 では、ユーザによる
%RIMF の使用を許可するためには、以下のいずれかに該当する必要があります。
-
ルーチン・コンパイルに対応するソース・コードが存在すること
-
入力ファイルが、Caché 5.0 システムの
%ROMF ユーティリティ内で格納されたオブジェクト・コードであること
Important:
インターシステムズのパートナーが、アプリケーションをオブジェクト・コード形式のみで配布する場合、この問題に特に注意してください。
今回のバージョンでは、オブジェクト・ベースのアプリケーションの開発に関連する、多くの新機能や強化された機能が提供されています。
新バージョンの Caché スタジオは、ルーチンの編集だけでなく、クラスの編集もサポートしています。Caché スタジオの新機能は、以下の通りです。
-
あらゆる機能を備え、構文を色付けできるスタジオ・エディタを使用した、クラス定義の編集のサポート
-
簡単に使用できるクラス・インスペクタによる、クラス定義の高速な検査と編集
-
Basic と Java のメソッド編集のサポート
-
Web サービス・ウィザードを含む、クラス開発を簡素化する、新規の一連のウィザード
-
オブジェクトを使用した開発のマルチユーザ・サポート
-
-
スタジオ・テンプレートを使用した、カスタム拡張のサポート
-
アプリケーション開発の管理に役立つプロジェクトのサポート
-
-
スタジオ・エディタでの、関数やコマンドにおけるコンテキストを区別するヘルプ
クラスの編集やデバッグをサポートするために、新規のスタジオは Caché v5.0 以降で利用可能なサーバ機能を必要とします。 したがって、Caché の古いバージョンで、このバージョンのスタジオを使用することはできません。
Caché オブジェクト・アーキテクトは、今回のリリースでは Caché から外され、そのすべての機能は、Caché スタジオに統合されました。
XML サポートの向上のために、ファイル内のクラス定義の表示方法として、Caché は新しい XML ベースの形式をサポートしています。この形式は、従来の形式にはない、以下のような複数の利点を提供します。
-
標準 XML を基にしており、より多くのツールと相互運用できます。
-
プログラム的に操作がより簡単で、コード生成のテクノロジーの開発もより簡単になっています。
-
将来の Caché バージョンとの作業をより簡単にする拡張性を提供しています。
-
CDL 形式よりも、ロードとエクスポートが非常に高速です。
現在、スタジオのインポート、またはエクスポートのすべての機能は、この形式を使用します。
プロジェクト定義、ルーチン、グローバル、および CSP ファイルを、この XML ファイル内に格納することもできます。
従来の CDL (クラス定義言語) 形式は、今回のリリースでもサポートされており、Caché に CDL 形式をインポートし、Caché からエクスポートすることができます。今回のリリースを開始するときは、新しい XML 形式を使用しなければなりません。
インポート・ユーティリティは、ファイル拡張子を使用して、クラス定義をロードするのに、従来の CDL 形式 (
.cdl) または新規の XML ベースの形式 (
.xml) のどちらを使用するかを決定します。
今回のバージョン 5 のオブジェクト・モデルでは、前回のバージョン 4 にはない多くの新機能が提供されています。 バージョン 5 の CDL ファイルをエクスポートする場合、そのファイルはバージョン 4 システムにはロードすることができません (既定)。
Note:
ExportCDL は、互換性のない機能 (PROCEDUREBLOCK/WEBMETHOD など) がエクスポートされたクラスに存在する場合、エクスポートされた CDL ファイルにコメントを追加します。
ExportCDL は、4.x システムに存在しないスーパー・クラスやタイプ、および LANGUAGE 値をチェックしません。
Caché スタジオでは、ドキュメントの例にあるように、新規のテキスト・ベースのクラス定義が使用されます。この新規のクラス定義は、CDL よりも容易に使用でき、スタジオで直接編集できるように設計されています。
Caché クラス・コンパイラは、以下のように機能拡張されています。
-
-
-
-
クラス・コンパイラが生成するコードのコンパクト化および効率化。クラスは従来よりもサイズの大きな少数のルーチンにコンパイルされるため、(ルーチン内呼び出しよりも遅い) 余分なルーチン間呼び出しが減少します。
-
-
クラス・コンパイラがコードを生成するとき、生成されたルーチン内の各タグ名の最初には、
z が付きます。例えば、
MyMethod と呼ばれるメソッドは、
zMyMethod と呼ばれるタグ名を生成します。
これは、メソッド名と Basic での予約語との衝突を回避するために変更されています (例えば、この変更がない場合、
Print と呼ばれるメソッドに対して生成されたコードでは、エラーが発生します)。
Note:
これらの強化された機能は、以下を除いて、アプリケーションのパフォーマンスを向上させる以外に影響はありません。使用しているアプリケーションが、
^oddDEF グローバルもしくは
^oddCOM グローバルへの直接参照を使用して、クラス・ディクショナリ構造への直接参照を作成する場合、またはそのアプリケーションがクラス・ディクショナリ構造を参照するマクロを使用する場合、この情報にアクセスするには、ドキュメント化されたマクロを使用するようにアプリケーションを変更する必要があります。
Caché オブジェクト・モデルには、強化された多くの機能が提供されています。以下は その概要です。
-
-
クラス定義をコンパイル、または削除するときに、クラス・コンパイラによって実行されるオペレーションを指定する新規のクラス・メンバ
Projection。このメカニズムを使用して、クラス定義をコンパイルするときは常に Java、C++、または EJB プロキシ・クラスが自動的に作成されるようにできます。
-
クラスのタイプ (persistent、または data type など) を指定する、列挙された新規の
ClassType クラス・キーワード。 これは、個別のブーリアン・クラス・キーワード (
Persistent など) を置換します。クラス・ディクショナリをアップグレードすると自動的にクラス定義が更新され、この新規のキーワードを使用するようになります。
-
メソッドが使用するスクリプト言語を指定する、新規の
Language キーワード。これはクラス全体、またはメソッド単位の両方で利用できます。これによりユーザは、メソッドの Caché ObjectScript、Basic や Java を指定することができます。
-
Caché ObjectScript プロシージャ・ブロックが、生成されたコードで使用されることを指定した、新規の
ProcedureBlock キーワード。これはクラス全体、またはメソッド単位の両方で利用できます。
これらすべては、以前のバージョンと上位互換性があります。
クラスやメソッド・レベルで
ProcedureBlock キーワードを指定することにより、Caché ObjectScript 内でプロシージャ・ブロックのサポートを使用できるようになります。
プロシージャ・ブロックは、メソッドの変数スコープのルールをより自然な振る舞いに変更します。
-
メソッドで使用されたすべての変数は、そのメソッドに対してプライベートであると見なされます。その変数で
New コマンドを使用する必要はなく、また変数は、そのメソッド内でのみ有効です。
作成された新規の任意のクラスは、プロシージャ・ブロックを使用します (使用できないようにすることもできます)。既存のクラスには、変更はありません。今回の変更は、既存のコードが今回のリリースで互換性を持つように設計されています。
メソッド・ジェネレータは、オブジェクトを利用して (メタ情報を提供し、コード生成を制御するため)、開発が非常に容易になりました。従来のメソッド・ジェネレータも、互換性のために使用できます。詳細は、
メソッド・ジェネレータ を参照してください。
%ResultSet オブジェクトの一般的な使用は、各フィールド値を取得するための、多くのメソッドの呼び出しを使用するコードを導きます。例えば、以下は一般的なループです。
While (result.Next()) {
Write result.Get("Name")," - ",result.Get("Address"),!
}
Get の各呼び出しは、プロパティ値の読み込みよりも高価なメソッドの呼び出しです。結果セットへのアクセスをより高速にするため、新しい多次元プロパティ
Data を使用することができます。このプロパティの値は、列名でインデックスされるので、上記のループは以下のようになります。
While (result.Next()) {
Write result.Data("Name")," - ",result.Data("Address"),!
}
ストアド・プロシージャとして投影されたメソッドは、最初の仮引数をタイプ
%SQLProcContext として宣言する必要はありません。新しい変数
%sqlcontext を、仮引数の代わりに使用することができます。メソッドが
%SQLProcContext のタイプとして宣言された最初の引数を持っている場合、ストアド・プロシージャとしてサーバからメソッドが呼び出されたとき、
%sqlcontext が最初の引数として渡されます (既存のメソッドとの互換性を確実にするため)。引数の有無を確認するための要件は、以前と同様です。
ClassMethod UpdateProcTest(zip As %String, city As %String, state As %String)
As %Integer [ SqlProc ] {
New SQLCODE,%ROWCOUNT,%ROWID,rowcount
&sql(UPDATE Sample.Person
SET Home_City = :city, Home_State = :state WHERE Home_Zip = :zip)
// Return context information to client via %SQLProcContext object
If ($g(%sqlcontext)'=$$$NULLOREF) {
Set %sqlcontext.SQLCode = SQLCODE
Set %sqlcontext.RowCount = %ROWCOUNT
}
QUIT 1
}
この変更は完全に、後方互換性のためです。 既存のストアド・プロシージャは変更しないで実行できます。
ユーザ定義のクラス・クエリ・メソッドの配列としての QHandle
既存のコードは実行を継続します。 この場合、
QHandle は、トップ・レベルのノードのみが定義されている配列とみなすことができます。
今回のリリースでは、Caché は一連の XML ベースの豊富な機能をサポートします。その機能は、以下の通りです。
-
XML ドキュメントとしてオブジェクト・インスタンスを自動的に投影する機能
-
XML ドキュメントをオブジェクト・インスタンスにインポートする機能
-
完全な XML DTD や Caché 内からのスキーマ検証をサポートする、完全に統合された XML プロセッサ (SAX ベース)
-
Web サービスや SOAP の自動的なサポート (XML ベースのリモート・プロシージャ呼び出しメカニズム)
-
XML ドキュメントとしてクラス定義をインポート、またはエクスポートする機能
-
Caché を使用して開発された、XML ベースのオンライン・ドキュメント・システム
Caché の今回のリリースでは、Caché ObjectScript に加え、Basic や Java のメソッドを定義することもできます。
Class MyClass Extends %RegisteredObject {
/// A Basic Method
Method MyMethod() As %Integer [language = basic]
{
For i = 1 To 10
person = New Sample.Person()
person.Name = "John " & i
person.%Save()
Next
Return 1
}
/// A Java method
Method Add(a As %Integer, b As %Integer) As %Integer [language = java]
{
return a + b;
}
}
Basic メソッドは実行可能な Caché コードにコンパイルされ、Caché 仮想マシンによって (Caché ObjectScript とまったく同じ方法で) 実行されます。Java メソッドは Caché Java バインディングによって生成された Java クラスに自動的に配置され、Java 仮想マシン (JVM) で実行されます。Caché は JVM を提供しませんが、標準 JVM で使用できます。
Caché アクティベート ActiveX ゲートウェイ
Caché の今回のリリースでは Caché アクティベートを提供しています。アクティベートは ActiveX ゲートウェイであり、アプリケーションが、Caché からの ActiveX コンポーネントをネイティブ・オブジェクトであるかのように使用できる機能を提供します。また、スタジオからもアクセス可能なウィザードでは、ActiveX コンポーネントから ActiveX ラッパ・クラスを自動的に生成することもできます。
Caché の今回のリリースでは、Caché の実行時エンジン管理オブジェクト参照を持つことで、オブジェクトの能力を向上させています。以前のバージョンでは、オブジェクト参照 (OREF) の管理は、オブジェクト・ライブラリによって処理されます。 基本のシステムは OREF の値とその他の値を区別しません。システムの OREF のサポートによって、実行時のエンジンは特定の値を OREF として認識し、オブジェクトのライフ・サイクルの管理と参照カウントを自動的に提供します。
-
インスタンス化されたオブジェクトを参照する変数がない場合、自動的にそのオブジェクトは消滅します。
-
-
メソッドの実装で Basic を使用するアプリケーションは、Caché ObjectScript コードと継続的に相互運用できます。
-
プログラミングはより簡単になり、OREF 値と OID 値に関する混乱や不適切な参照による問題も解消されました。
%Close メソッドへの不必要な呼び出しがなくなり、性能は向上しました。
オブジェクト変数は、参照カウントを自動的に管理します。 参照カウントとは、現在オブジェクトを参照している項目の数です。オブジェクトを参照する変数やオブジェクトのプロパティを設定する度に、オブジェクトの参照カウントは自動的にインクリメントされます。変数がオブジェクトへの参照を停止 (範囲外になった場合、削除された場合、または新しい値が設定された場合) すると、参照カウントはディクリメントされます。このカウントが 0 になると、オブジェクトは自動的に消滅します (メモリから削除されます)。
Method Test()
{
Set person = ##class(Sample.Person).%OpenId(1)
Set person = ##class(Sample.Person).%OpenId(2)
}
このメソッドは
Sample.Person のインスタンスを作成し、そのインスタンスに対する参照を変数
person に配置します。そして、
Sample.Person の別のインスタンスを作成し、
person の値を新しいインスタンスに対する参照に変更します。ここで、最初のオブジェクトを参照しているものがなくなり、消滅します。メソッドの最後で、
person は範囲外になり (このメソッドがプロシージャ・ブロックを使用するので)、2 番目のオブジェクトは消滅します。以前のバージョンでは、これらのオブジェクトはクローズされていませんでした (
%Close メソッドに対する明示的な呼び出しがない場合)。
他の例は、コレクション内のオブジェクトを繰り返します。
Method Total(invoice As Invoice) As %Integer
{
Set total = 0
Set count = invoice.LineItems.Count()
For i = 1:1:count {
Set lineitem = invoice.LineItems.GetAt(i)
Set total = total + lineitem.Amount
}
Quit total
}
ここでは、
LineItems コレクション内の各オブジェクトを連続してオープンし、その
Amount を実行中の合計に追加します。オブジェクトが変数
lineitem に割り当てられるたび、それが参照していた前のオブジェクトはメモリから削除されます。
任意のローカル変数、またはローカル配列ノードは、OREF 値を含むこともあります。以下はその例です。
Set array(1) = ##class(Sample.Person).%New()
Set array(2) = ##class(Sample.Person).%New()
Set array(3) = ##class(Sample.Person).%New()
Set array(4) = "string"
Kill array
ここでは、3 つの新規のオブジェクト・インスタンスを生成し、それに対する参照を
array の 3 つのノードに配置します。配列を削除するとき、オブジェクトは消滅します (それに対する参照がないからです)。上記の
array(4) のように、配列内ではオブジェクト値と非オブジェクト値を混合できます。
OREF 値を文字列として使用する場合、値は文字列に自動的に変換されます。
Set object = ##class(Sample.Person).%New()
Write object // implicitly convert object to a string
-
Set oref = ##class(Sample.Person).%New()
Write oref
-
Set oref = ##class(Sample.Person).%New()
Set string = oref _ " "
Write string
-
Set oref = ##class(Sample.Person).%New()
Set list = $LB(oref)
Write $ListGet(list,1)
-
Set oref = ##class(Sample.Person).%New()
Set ^otest = oref
Write ^otest
-
Set oref = ##class(Sample.Person).%New()
Set array(oref) = "test"
Write array(oref)
OREF 値を整数として使用する場合、OREF 値は数字に変換されます。
Set object = ##class(Sample.Person).%New()
Write +object // implicitly convert object to a number
Note:
文字列や数値は、オブジェクト参照に変換できません。
文字列や数値を OREF として使用しようとすると、<INVALID OBJECT> エラーが発生します。以下はその例です。
Set object = ##class(Sample.Person).%New()
Set object.Name = "Jack"
Set x = +object // set x to numeric value of OREF
Write x.Name // <INVALID OBJECT>
これは、値が一度、非 OREF に変換されると、それに関連する参照カウントが存在しなくなるからです。文字列や数値を OREF に変換する能力は、信頼できないコードを生成する可能性があります。 その変換を行うと、同じオブジェクトが存在し続けることを保証できません。
%New メソッドは、新しいシステム・レベルの最適化機能を備え、オブジェクトの作成がより高速になりました。
システム OREF のサポートにより、
%Close メソッドの役目はなくなりましたが、既存のアプリケーションとの互換性のために存在します。
今回のリリースへのアップグレードのプロセスを簡素化するため、
%Close メソッドの従来の振る舞いを有効にする方法があります。既定では、
%Close はバージョン 5 では何も行いません。
現在のプロセスに対する
%Close の従来の振る舞いを有効にする方法は以下の通りです。
現在のプロセスに対する
%Close の従来の振る舞いを無効にする方法は以下の通りです。
また、すべてのプロセスに対して
%Close の従来の振る舞いを設定することもできます。
これは、このコマンドの
呼び出し後 に開始したすべてのプロセスに影響を与えます。 このコードは、使用しているシステムの初期化ルーチンに配置します。
%Close の従来のサポートを有効にすると、
%Close メソッドは旧バージョンと同様に動作を継続します。これはオブジェクトのオブジェクト・レベル参照カウントをディクリメントし、そのカウントが 0 に到達すると、メモリから削除します。 従来のモードでは、オブジェクトはシステム・レベルのカウントに加え、オブジェクト・レベルの参照カウントも含むことに注意してください。このオブジェクト・レベルのカウントは、システムの OREF 管理に影響を受けません。
システムの OREF サポートによって、以下のコードはオブジェクト・インスタンスを作成し、そのインスタンスに対するすべての参照が削除されたときに、そのインスタンスを削除します。
Set obj = ##class(Sample.Person).%New()
Set obj = "" // object is now destroyed
アプリケーションがあるオブジェクトの
%Close を呼び出した場合、そのオブジェクトはその時点 (参照カウントが 0 になったとみなされて) 削除され、使用されていた OREF 値は
不活性化されます。つまり、この OREF 値に対するすべての参照が削除されるまで、その値は他のオブジェクトを参照するのに使用されないということです。
Set obj = ##class(Sample.Person).%New()
Do obj.%Close() // object is closed; OREF value is "suspended"
Set obj = "" // OREF value is removed
停止中の OREF 値を使用すると、実行時エラーが発生します。これは以前のバージョンでも見られた、オブジェクトがクローズされた後に、そのオブジェクトを使用することと、基本的に同じ振る舞いです。
Note:
%Close メソッドの従来のサポートは、Caché バージョン 5 以降では
サポートされない 予定です。その時点で、
%Close メソッドの機能はまったく消滅します (そしてすべてのアプリケーションの動作速度がわずかに向上します)。v5.0 にアップグレード後、アプリケーションが
%Close の新しい振る舞いの元で正常に作動するかを確認するテストを行う必要があります。 このテストを行うことで、将来のバージョンへのアップグレードが可能になります。
%Close に依存してオブジェクトをクローズすることは不可能であることに注意してください (オブジェクトに対する未決の参照が存在することを伝えていないため)。このため、アプリケーションの大半は、変更しないで新しい
%Close の振る舞いを使用して実行することができます。
今回のバージョンには、任意の変数や式が、有効なオブジェクト参照を持っているかどうかをテストする、
$IsObject という新しい関数があります。以下の 3 つの値のうち、いずれか 1 つを返します。
今回のリリースでは、埋め込みオブジェクト参照が、その参照のプロパティを取得する前に設定されているかどうかの確認を不要にするため、Caché オブジェクトの機能を強化しています。多くの場合、オブジェクト参照が設定されていないとき、プロパティ値は空文字列として処理されます。今回のリリースでは、
Object.Embedded が既存のオブジェクト参照に対して設定されていない場合、
Object.Embedded.Property 形式のプロパティ参照は空文字列を返します。これは以前のバージョンでは、<INVALID OREF> エラーの原因となっていました。
Caché ObjectScript では、以下のコードは、
Write Object.Embedded.Property
Write $SELECT(Object.Embedded'=$$$NULLOREF:Object.Embedded.Property,1:"")
システム・オブジェクト参照のサポートを使用するためのアップグレード
システム OREF サポートの大半は、現在のシステムとの上位互換性を持っています。OREF 値を非オブジェクト (整数、または文字列) で使用するアプリケーションでは、問題が生じる場合があります。これは、以下のセクションで詳細に説明します。
OREF がグローバル内に保存されるとき、OREF は文字列値に変換されます。以下のコードは、旧バージョンでは動作していましたが、Caché 5.0 では実行時エラーの原因となります。 文字列値をオブジェクト参照として使用しているからです。
Set obj = ##class(Sample.Person).%New()
Set ^global(1) = obj
//...
Set a = ^global(1)
Write a.Name // <INVALID OBJECT> error
数値は OREF として使用できないので、以前のバージョンで使用していた (1 の値を持つ OREF が存在する場合) 以下のコードを使用すると、実行時エラーが発生します。
Do (1).Method() // <INVALID OBJECT> error
OREF 値を文字列の一部として、または
$List 構造の内部 (システムに関する限り、
$List 構造は文字列) に保存するとき、OREF は文字列値に変換されます。以前のバージョンで使用していた以下のコードを使用すると、OREF 値として文字列を使用しようとするため、実行時エラーが発生します。
Set obj = ##class(Sample.Person).%New()
Set list = $ListBuild(obj)
// ...
Set x = $ListGet(list,1)
Write x.Name // <INVALID OBJECT> error
区切り文字列、または
$List 構造内部に OREF 値を格納する場合、使用中のコードを変更する必要があります。この場合、そのコードを変換してローカル配列を (OREF 値を含むことができる) 使用することをお勧めします。
Set obj = ##class(Sample.Person).%New()
Set array(1) = obj
特定のアプリケーションは、Caché プロセスと外部コンテキストの間に OREF 値を渡します。例えば、OREF の整数値をクライアント・アプリケーション (Java や Visual Basic など) に送り、その後、オブジェクト参照として使用を継続しながら、その値をサーバに返します。整数値を OREF に戻す変換はできないので、この操作はできなくなりました。
Note:
ドキュメント化された形式で Caché で提供されている標準 Active X と Java バインディングを使用している場合は、クライアントとサーバ間でオブジェクトを使用しても問題はありません。 Caché が自動的にこの状況を管理します。
Caché 外部でオブジェクトを渡し、それを戻した場合、以下の技術を使用することをお勧めします。
-
クライアントに送信したオブジェクト参照の追跡するために、サーバ上でローカル配列を使用します。
-
この配列内で、添え字として (他の OREF 値との衝突を避けるため) OREF の数値を使用し、ノード値として OREF 値を配置して、OREF を保存します。
Set %myobjects(+obj) = obj
この配列に保存されたオブジェクト参照は、ユーザがオブジェクトを使用する準備ができるまで、そのオブジェクトは存在することを保証し、真の OREF を提供します。