$ESTACK (ObjectScript)
構文
$ESTACK
$ES
概要
$ESTACK には、ユーザ定義のポイントから、ジョブのコール・スタック上に保存されている、コンテキスト・フレーム数が含まれます。このポイントを指定するには、NEW コマンドを使用して $ESTACK の新しいコピーを作成します。
$ESTACK 特殊変数は、$STACK 特殊変数と類似しています。どちらの変数にも、ジョブまたはプロセスのコール・スタックに現在保存されているコンテキスト・フレームの数が格納されます。コンテキストが変更されると、両方の変数がインクリメントされ、復元されます。主な違いは、NEW コマンドを使用することで、いつでも $ESTACK のカウントをゼロにリセットすることができる点です。$STACK のカウントをリセットすることはできません。
コンテキスト・フレームとコール・スタック
InterSystems IRIS イメージが開始すると、コンテキストがコール・スタックに保存される前は、$ESTACK と $STACK の値は 0 です。DO でルーチンが別のルーチンを呼び出すたびに、現在実行中のルーチンのコンテキストがコール・スタックに保存され、$ESTACK と $STACK がインクリメントされて、新しく作成されたコンテキストで、呼び出されたルーチンの実行が開始します。呼び出されたルーチンは、順番に別のルーチンを呼び出すことができます。別のルーチンが呼び出されるたびに、$ESTACK と $STACK がインクリメントされ、コール・スタックに保存されたコンテキストが増えていきます。
DO コマンド、XECUTE コマンド、またはユーザ定義関数への呼び出しを発行すると、新しい実行コンテキストが作成されます。GOTO コマンドを発行しても、新しいコンテキストは作成されません。
DO コマンド、XECUTE コマンド、またはユーザ定義関数参照によって新しいコンテキストが作成されると、$STACK と $ESTACK の値がインクリメントされます。コンテキストが QUIT コマンドで終了するたびに、前のコンテキストはコール・スタックから戻され、$STACK と $ESTACK の値はディクリメントされます。
$ESTACK および $STACK 特殊変数は、SET コマンドを使用して変更することはできません。変更を試みると、<SYNTAX> エラーが返されます。
新規の $ESTACK の作成
NEW コマンドを使用して、コンテキストで $ESTACK の新しいコピーを作成できます。InterSystems IRIS は以下を実行します。
-
$ESTACK の古いコピーを保存します。
-
値 0 を使用して、$ESTACK の新規コピーを作成します。
この方法で、$ESTACK レベル 0 コンテキストとして、特定のコンテキストを作成することができます。DO、XECUTE、またはユーザ定義関数によって新しいコンテキストが作成されると、この $ESTACK の値がインクリメントされます。しかし、新しい $ESTACK が作成された (レベル 0 の $ESTACK) コンテキストを終了すると、$ESTACK の前のコピーの値が復元されます。
例
次の例は、$ESTACK に対する NEW コマンドの影響を示しています。この例では、MainRoutine によって $STACK と $ESTACK の初期値 (同一の値) が表示されます。続いて、Sub1 が呼び出されます。この呼び出しによって、$STACK と $ESTACK がインクリメントされます。NEW コマンドによって、値 0 の $ESTACK が作成されます。Sub1 によって Sub2 が呼び出されて、$STACK と $ESTACK がインクリメントされます。MainRoutine に戻ると、$STACK と $ESTACK の初期値がリストアされます。
Main
WRITE !,"Initial: $STACK=",$STACK," $ESTACK=",$ESTACK
DO Sub1
WRITE !,"Return: $STACK=",$STACK," $ESTACK=",$ESTACK
QUIT
Sub1
WRITE !,"Sub1Call: $STACK=",$STACK," $ESTACK=",$ESTACK
NEW $ESTACK
WRITE !,"Sub1NEW: $STACK=",$STACK," $ESTACK=",$ESTACK
DO Sub2
QUIT
Sub2
WRITE !,"Sub2Call: $STACK=",$STACK," $ESTACK=",$ESTACK
QUIT
次の例は、DO および XECUTE コマンドを発行することによって新しいコンテキストが作成されたときに $ESTACK の値がどのようにインクリメントし、それらのコンテキストが終了したときにどのようにディクリメントするかを示しています。また、GOTO コマンドでは新しいコンテキストの作成も $ESTACK のインクリメントも行われないことも示しています。
Main
NEW $ESTACK
WRITE !,"Initial Main: $ESTACK=",$ESTACK // 0
DO Sub1
WRITE !,"Return Main: $ESTACK=",$ESTACK // 0
QUIT
Sub1
WRITE !,"Sub1 via DO: $ESTACK=",$ESTACK // 1
XECUTE "WRITE !,""Sub1 XECUTE: $ESTACK="",$ESTACK" // 2
WRITE !,"Sub1 post-XECUTE: $ESTACK=",$ESTACK // 1
GOTO Sub2
Sub1Return
WRITE !,"Sub1 after GOTO: $ESTACK=",$ESTACK // 1
QUIT
Sub2
WRITE !,"Sub2 via GOTO: $ESTACK=",$ESTACK // 1
GOTO Sub1Return
ターミナル・プロンプトから呼び出す場合のコンテキスト・レベル
プログラムから呼び出されるルーチンは、ターミナル・プロンプトから DO コマンドを使用して呼び出すルーチンとは異なるコンテキスト・レベルで開始します。ターミナル・プロンプトで DO コマンドを入力すると、呼び出すルーチンの新しいコンテキストが作成されます。
呼び出すルーチンは、$ESTACK レベル 0 コンテキストを作成してから、すべてのコンテキスト・レベル参照に $ESTACK を使用することによって、補正することができます。
以下のルーチンを考慮してみましょう。
START
; Establish a $ESTACK Level 0 Context
NEW $ESTACK
; Display the $STACK context level
WRITE !,"$STACK level in routine START is ",$STACK
; Display the $ESTACK context level and exit
WRITE !,"$ESTACK level in routine START is ",$ESTACK
QUIT
プログラムから START を実行すると、以下が表示されます。
$STACK level in routine START is 0 $ESTACK level in routine START is 0
ターミナル・プロンプトで DO ^START を発行して START を実行すると、以下が表示されます。
$STACK level in routine START is 1 $ESTACK level in routine START is 0
$ESTACK とエラー処理
$ESTACK は特に、エラー・ハンドラが特定のコンテキスト・レベルにコール・スタックを巻き戻す必要があるときのエラー処理中に利用できます。エラー処理の詳細は、"TRY-CATCH の使用法" を参照してください。