MSM アプリケーションの変換
Caché の MSM 言語互換モードを使用して、より少ない変更で MSM アプリケーションを実行できる場合でも、MSM 固有言語機能をネイティブの Caché コードに変換することを強くお勧めします。変換は、ObjectScript などの、Caché 固有の機能を活用する第一歩となります。
以下の項目について説明します。
ルーチンの違い
ルーチンでの操作が、Caché では MSM とわずかに異なります。
MSM のアプローチ :
-
プログラマがルーチン・ソース・コードで作業し、それを (暗黙的にまたは明示的に) ZSave します。コードは、それがどのように変更されたかにかかわらず、暗黙的にオブジェクト・コードにコンパイルされます。
-
ソースとオブジェクト・コードの両方がルーチン・ブロック上のディスクに一緒に格納されます。
-
実行時に、オブジェクト・コードはバッファ・プールの汎用バッファにロードされます。
Caché のアプローチ :
-
プログラマは INT (中間) コードか MAC (マクロ) コード、または INC (インクルード) コードで作業します。これらは、ルーチン名の拡張子になります (A123.mac など)。
Caché で MSM ソースに相当するものは、INT コードです。マクロ・コードは、埋め込み SQL を直接コードに挿入する時など、マクロ文を埋め込む場合に便利です。
-
プログラマはスタジオを使用してルーチンを編集しますが、ルーチンでは OBJ オブジェクト・コードファイルを生成するのに明示的なコンパイルを必要とします (MSM p-code に相当)。
MAC コードを Caché でコンパイルすると、自動的に INT コードと OBJ コードが生成されます。また、INT コードをコンパイルすると、自動的に OBJ コードが生成されます。
-
すべてのコードはグローバル (^rMAC、^rINV、^rOBJ、および ^ROUTINE) に格納されます。
-
実行時に、OBJ コードのみが、主なグローバル・バッファ・プールから独立した専用のルーチン・バッファにロードされます。これにより、明らかな利点がもたらされます。
MSM ルーチンの移植
以下の手順を使用して、サイズが 64KB 以下の MSM ルーチンを移行します。
-
^%RS ユーティリティを使用して、MSM ルーチンを MSM 形式で保存します。
-
宛先のネームスペースで ^%SYS.RI を使用して、コードを Caché にリストアします。
-
宛先のネームスペースから、^%RCOMPIL を使用して Caché 内でコードをリコンパイルし、構文エラーをチェックします。どのルーチンが <SYNTAX> エラーを生成しているか判明したら、"Caché ObjectScript リファレンス" を参照して、Caché の言語構文に精通するようにしてください。
MSM では、現在のスタックとパーティションのサイズで許可される限り、どんなに大きいルーチンでもサポートできますが (200 KB までテスト済み)、Caché ルーチンは 64KB より小さいサイズにコンパイルする必要があります。MSM の ^%RSIZE ユーティリティを使用して、Caché にインポートする前にルーチン・サイズをチェックできます。ルーチンの大きさを計算するには、^%RSIZE で報告されるテキスト・ブロックの数を 1 KB で乗算します。
64KB 以上の MSM ルーチンは、次の 2 つの方法のいずれかで処理できます。
-
まず MSM 内のルーチンを分割し、64KB を超えるルーチンが存在しないようにし、その後 Caché にインポートします。
-
まずルーチンを Caché にインポートします。その際、構文チェックとコンパイルのオプションをオフにします。Caché にインポートしたら、ルーチンを分割し、^%RCOMPIL を使用してそれらをコンパイルします。
P-code としてのみ格納されている MSM ルーチン (Caché ではオブジェクト・コードとして知られています) を移行することはできません。P-code としてのみ提供されるルーチンを移行する必要がある場合は、作業を進める前に、アプリケーションのサプライヤに連絡して、ルーチンのソース・コードを取得する必要があります。
MSM 言語互換モード
Caché は、移植された MSM ルーチンで作業する場合、MSM 言語モードで操作します。言語モードは、各ルーチンごとに個別に設定されます。ある言語モードでコンパイルされたルーチンは、別のモードでコンパイルされたルーチンを呼び出すことも、呼び出されることもできます。したがって、例えば MSM モードのルーチンが Caché モードのルーチンを呼び出し、この Caché ルーチンが別の MSM モードのルーチンを呼び出すことができます。
言語モードを切り替えるには、$ZU (55,モード) を使用します。モードは言語モードの数字です。関連する設定は以下のとおりです。
-
MSM モードへの切り替え :
Set x=$ZU(55,8)
-
ネイティブ Caché モードへの切り替え :
Set x=$ZU(55,0)
-
現在の言語モードを返す :
Set x=$ZU(55)
MSM アプリケーションを正しい言語モードでコンパイルすると、システムで使用するアプリケーションや言語モードに関係なく、任意の Caché システムにインストールして、実行できます。言語モード処理の大半は、実行時ではなくコンパイル時に行います。その結果、MSM のような言語モードを使用しても通常は、Caché のネイティブ言語モードと同様に、高性能に動作できます。
各プロセスの既定のモードは、ネイティブ Caché モードです。特定のプロセスの種類に対するこの既定のモードを変更するには、^%ZSTART ルーチン内で適切な行タグを変更する必要があります。
これらのモードのいずれかで、ユーザ独自のコマンド、関数、特殊変数を追加して、MSM の %ZZCMNDS、%ZZFUNCS、および %ZZSVARS MSM ルーチンを変換できます。現在の言語モードによっては、対応する Caché ルーチンが 、これらの追加された機能に対して検索されます。
コマンド | 関数 | 変数 | |
---|---|---|---|
Original (native MSM) routines | %ZZCMNDS | %ZZFUNCS | %ZZSVARS |
ネイティブ Caché モードのルーチン | ^%ZLANGC00 | ^%ZLANGF00 | ^%ZLANGV00 |
MSM モードのルーチン | ^%ZLANGC008 | ^%ZLANGF008 | ^%ZLANGV008 |
これらのルーチンに入力する行タグは、新しいコマンド、関数、または特殊変数の名前となります。入力される行タグは、“Z” で始まり、すべて大文字である必要があります。コマンド、関数、または特殊変数を実際に実行する際は、大文字と小文字は区別されません。
-
以下に示すように、^%ZLANGC* にコードを追加すると、ZSS のような新しいコマンドが作成されます。
%ZLANGC008 ZSS ; do a System Status Do ^%SS Quit
-
以下に示すように、^%ZLANGF* にコードを追加すると、$ZRTN(X) のような新しい関数が作成されます。
%ZLANGF008 ZRTN(x) ; find out what routine a process is currently running Quit $Print($View(-1,x),"^",6)
-
以下に示すように、^%ZLANGV* にコードを追加すると、$ZTIME のような新しい特殊変数が作成されます。
%ZLANGV008 ZTIME ; return the current time Do INT^%T Quit %TIM
上記で定義したルーチンを呼び出すカスタム・コードの例は、以下のとおりです。
MyRtn ; Call the code added to the ^%ZLANG* routines
;
New pid,rtn,x
Set x=$ZU(55,8) ; Change to MSM mode
ZSS
Read !,"Enter a process ID: ",pid
Set rtn=$ZRTN(pid)
If rtn="" Set rtn="no routine"
Write !,"At "_$ZTIME_", process #"_pid_" was running "_rtn_"."
Set x=$ZU(55,0) ; Return to native mode
Quit
非標準関数および機能の変換
MSM 実装固有の関数と機能の変換は、変換で最も複雑な部分です。次の点に注意してください。
-
ZUSE のような多くの MSM コマンド、$ZOS などの関数、および $SYSTEM などの特殊変数は、Caché とは異なった方法で処理する必要があります。
-
MSM のメモリ構造にアクセスする VIEW コマンドまたは $VIEW 関数は、削除するか変更する必要があります。
-
MSM ユーティリティに対する参照は、すべて変換する必要がある場合があります。
-
Caché は、hex 演算子 # をサポートしません。ただし、$ZHEX に対するサポートは同じなので、この関数は適切な場所で使用する必要があります。
-
Caché はプリンタ・ニーモニックをサポートしません。
-
^%RHANGE ユーティリティは、単純な構文の変更を行うために使用される場合もありますが、ルーチンを無差別に修正すると、コードが不要に変更される場合があるため、この方法は注意して使用する必要があります。大部分のコードの変更は、プログラマにより対話的に実行される必要があります。
MSM から Caché への変換に必要な作業を大まかに理解するために役立つ、いくつかの推奨されるアクションを以下に示します。
-
すべての MSM ルーチンを Caché にロードし、%RCOMPIL を実行して構文エラーを分析します。
-
ほとんどの OPEN コマンドと USE コマンドは、ここに表示される必要があります。
-
外部の空白文字は、一般的な問題となります。MSM でルーチンのコンパイルが成功しても、Caché が外部の空白文字のためにコンパイル時に <SYNTAX> エラーを生成することがあります。空白文字の問題は、プログラマによって対話的に修正されるのが最善です。この例として、QUIT コマンドとセミコロンの間の 2 つ未満の空白があります。
-
ルーチン内での重複する行タグの名前は、Caché ではサポートされていません。そのようなルーチンをコンパイルすると、<LABELREDEF> エラーが生成されます。それらの行タグのどちらかを削除するか変更する必要があります。その上で、同じアプリケーション・ロジックを維持するために必要な変更を行ってください。
-
-
%RFIND を使用して以下の文字列を検索します。
-
$V (View)
-
$Z (一般的にシステム関数)
-
^%
-
^[
-
^|
-
^ ( ; “^” と “(“ (SPACE 演算子) の間の空白に注意してください。
-
O 51、O 52、O 53 または O 54 (名前ではなく、開いている数)
-
MSM コマンド、関数、演算子、プリプロセッサ指示文、特殊変数、構造化システム変数、およびそれらに相当する Caché 機能のリストについては、付録の “MSM と Caché ユーティリティ・カタログ” を参照してください。
MSM-XCALL 関数
XCALL 関数では、C や Assembler などの外部プログラムを使用して、M 内から呼び出すことができます。後方互換性のサポートのため、MSM は ZCALL インタフェースもサポートしています。XCALL と ZCALL は、コンセプトと実装の点で Caché の $ZF() 呼び出しインタフェースに似ています ("Caché コールアウト・ゲートウェイの使用法" を参照)。XCALL 関数および ZCALL 関数は、Caché $ZF() 関数に変換する必要があります。
%OS および $ZOS 経由の OS 関数
MSM の %OS ユーティリティおよび $ZOS 関数を使用すれば、多数の OS 関連関数を M 内から実行できます。Caché には、%OS または $ZOS に直接対応するものはありませんが、$ZF(-1)、$ZF(-2)、または (OPEN コマンドへの "Q" パラメータを使用した) OS コマンドへのパイプによって、どんな OS 関数でも簡単に実行できます。
一般的に、ファイル関連の演算 ($ZOS で使用されるように) はすべて、%Library.FileOpens in a new tab クラスへのメソッド呼び出しで置き換える必要があります。例えば、以下のようにファイルを削除します。
Set status=##class(%Library.File).Delete("filename")
Caché の $ZF(-1) 関数を使用すると、Caché プログラマ・プロンプトから OS コマンドを実行できます。Windows プラットフォームでは、これらのコマンドがユーザ入力を予期していた場合、コマンドはハングします。詳細は、"Caché コールアウト・ゲートウェイの使用法" の “オペレーティング・システム・コマンドの発行” を参照してください。
ZWINTERM 呼び出しの変換
MSM では、ポップアップ・ウィンドウを使用して ZWINTERM インタフェース経由のメッセージを表示できます。Caché では、これと同じ文字ベースのウィンドウ機能を取得するためのオプションがいくつかあります。
-
ニーモニック空間を使用して、ポップアップ・ウィンドウを作成します。
-
$ZF(-1) 関数を使用して、オペレーティング・システム・レベルのコマンドを発行し、新しいターミナル・ウィンドウを開きます。
-
MSM を Caché へのネットワーク・クライアントとして維持し、既存の文字ウィンドウ機能が使用できるようにします。これは、Caché への移行が進行中の間、優れた短期的な目標となります。
MSM プリプロセッサ指示文
MSM および Caché はどちらも、プリプロセッサ指示文を使用してマクロの定義、マクロ・ライブラリの定義、他のルーチンからのソース・コードの組み込みなどのタスクを実行できるようにするメカニズムを備えています。
Caché は指示文を .MAC および .INC コードとして格納します。MSM グローバル ^ZMSMMAC および ^ZMSMSRC は、それぞれプリプロセッサ指示文とソース・コードを格納しますが、Caché では ^rMAC グローバルおよび ^ROUTINE グローバルがそれに相当します。
MSM と Caché は概念的によく似た機能を備えていますが、構文はこれらの 2 つのシステム間で異なっています。例えば、MSM ではマクロの仮パラメータ・リストを構築するのに、次の 2 つのメカニズムのどちらかを使用できます。
-
引数の仮名として、$1、$2、...$N のような列挙変数を使用
#define copyright() Copyright $1-$2
-
引数の仮名として、英数字を使用
#define copyright(from,to) Copyright from-to
Caché では、マクロのプリプロセスに対して列挙変数の使用をサポートしていません。代わりに、英数字名を参照する Caché メソッドを採用する必要があります。上記の MSM の例は、Caché では次のようになります。
#define copyright(%var1,%var2) "Copyright ",%var1,"-",%var2
Caché での仮パラメータ・リストの引数は、% 記号で始まる必要があります。Caché は MSM の $0 変数をサポートしていません。この変数は任意のマクロに渡された引数の数字を格納します。
MSM と Caché は、アプリケーション内からマクロが参照される方法においても異なります。上記のマクロ定義を使用して、MSM では以下の 2 つのメソッドのどちらかを使用して copyright マクロを参照できます。
-
括弧で囲まれたパラメータ・リスト内に引数を渡す。
%%copyright(1997,1998)
-
コンマで区切られたリストとして引数を渡す。
#%copyright 1997,1998
Caché では、マクロを参照するための %% および #% 構文はサポートされていません。次の構文を使用して copyright マクロを呼び出します。
$$$copyright(1997,1998)
グローバルおよびルーチンに対する拡張参照
前述したように、Caché は実際の物理データベース・ボリュームからデータにアクセスするのに、ネームスペースに依存しています。ご使用のアプリケーション内から Caché のネームスペースを採用することを強くお勧めします。ただし、アプリケーション内のすべてのハード・コード化された拡張参照を変更することは、短期的な目標として難しい場合があります。
Caché は以下のいくつかの拡張参照形式をサポートします。
グローバルの場合 :
^["namespace"]global
^["namespace",""]global
(this is useful if piecing apart an MSM UVI/VOL string)
^["directory","system"]global
^|"namespace"|global
^|"^system^directory"|global
ルーチンの場合 :
DO ^|"namespace"|routine
DO ^|"^system^directory"|routine
JOB ^routine["namespace"]
JOB ^routine["namespace",""]
JOB ^routine["directory","system"]
JOB ^routine["^system^directory"]
グローバルとルーチンの既定の位置として CACHESYS データベースを使用する MGR という名前の Caché ネームスペースを作成する必要が生じる場合があります。MGR がシステム・グローバルとルーチンを含むことを予期する拡張参照は、修正の必要はありません。
Caché での EOF (ファイルの終わり) 状況の処理
MSM では特殊変数 $ZC を使用して、最後にデバイスがアクセスしたときからの状況情報を格納します。特に、MSM アプリケーションは、READ コマンドがシーケンシャル・ファイルの終わりに到達したかどうかを確認するのに、$ZC を広く使用します (この場合 $ZC は 1 を返します)。Caché では、MSM とは異なり、この状況では <ENDOFFILE> エラーがトリガされます。Caché での EOF 状況を処理するには、アプリケーション内で $ZTRAP を使用してカスタム・エラー・トラップを作成する必要があります。
Caché では、$ZC (MSM 言語互換モードで使用されている場合) 特殊変数や $ZEOF (ネイティブ Caché 言語モードの場合) 特殊変数もサポートされます。
MSM および Caché データベース・ネットワーキング (DDP)
MSM データベース・ネットワーキング (DDP) と Caché データベース・ネットワーキング (DSM-DDP/DCP/ECP) との間には多くの違いがあります。
-
MSM は、Raw Ethernet 上の DSM-DDP (MSM データ・リンクとも呼ばれる) リンクによってのみ Caché と通信できます。このリンクには、MSMV3 リンクとは異なるパフォーマンス特性があります。MSM では、より遅くなります。
-
Caché ネットワーキングは、MSM RVG コンセプトをサポートしません。Caché ECP プロトコルは、すべての接続で MSM RVG と同様のネット・トラフィック最適化を使用しますが、MSM とは互換性がありません。
-
MSM DDP プロトコルのみがパラメータ渡しを行うジョブ起動をサポートします。
-
DSM-DDP を使用して Caché と通信する場合、データ・セット (データベース) のみにアクセスでき、ネームスペースにはアクセスできません。つまり、MSM では Caché におけるネームスペースのマッピングを使用できません。
-
MSM から Caché 上でリモート・ジョブを開始する場合、ネームスペースからグローバル・アクセスを行うジョブは開始できません。MSM は、既定のデータ・セット (データベース) を持つジョブのみを開始できます。つまり、MSM から開始されたジョブの場合、既定では Caché 内にネームスペースのマッピングはありません。