ダイナミック変数およびフィールドについて

このドキュメントでは、次のトピックについて説明します。


ダイナミック変数の用途

アプリケーションの開発時に大きなデータ構造(画像、音声、ビデオなど)の最大サイズが正確にわからない場合があるため、Natural では、英数字変数およびバイナリ変数を DYNAMIC という属性を使用して定義できるようにしています。この属性で定義されている変数の値スペースは、実行時に必要となったとき(割り当て操作#picture1 := #picture2 など)にダイナミックに拡張されます。つまり、Natural では、開発時に制限を定義せずに、大きなバイナリデータ構造および英数字データ構造を処理できます。ダイナミック変数の割り当て時には当然、使用可能なメモリ量の制限を受けます。ダイナミック変数の割り当てに対し、オペレーティングシステムからメモリ不足という結果が返された場合、ON ERROR ステートメントを使用してこのエラー条件をインターセプトできます。インターセプトしない場合、Natural によってエラーメッセージが返されます。

Natural システム変数 *LENGTH は、指定されたダイナミック変数に現在使用されている値スペースの長さ(コード単位)を取得するために使用できます。A および B フォーマットでは、1 つのコード単位のサイズは 1 バイトです。U フォーマットでは、1 つのコード単位のサイズは 2 バイトです(UTF-16)。*LENGTH は、ダイナミック変数を使用する割り当て中に、Natural によってソースオペランドの長さに自動的に設定されます。*LENGTH(field) は、したがって、Natural のダイナミックフィールドまたはダイナミック変数に現在使用されている長さ(コード単位)を返します。

ダイナミック変数のスペースが不要になった場合、REDUCE ステートメントまたは RESIZE ステートメントを使用して、ダイナミック変数に使用されていたスペースをゼロ(または他の任意のサイズ)に減らすことができます。特定のダイナミック変数に対するメモリの使用量がわかっている場合、EXPAND ステートメントを使用して、ダイナミック変数に使用するスペースをその特定のサイズに設定できます。

ダイナミック変数を初期化する必要がある場合、MOVE ALL UNTIL ステートメントを使用して初期化できます。

ダイナミック変数の定義

アプリケーションの開発時に大きな英数字データ構造またはバイナリデータ構造の実際のサイズが正確にわからない場合があるため、フォーマット A、B、U のダイナミック変数の定義を、これらの構造を管理するために使用できます。ラージ変数のダイナミックアロケーションおよび拡張(再割り当て)は、アプリケーションプログラミングロジックに対して透過的です。ダイナミック変数は長さを指定せずに定義されます。メモリは、ダイナミック変数がターゲットオペランドとして使用されるとき、実行時に暗黙的に割り当てられるか、EXPAND ステートメントまたは RESIZE ステートメントの使用によって明示的に割り当てられます。

ダイナミック変数は、以下の構文を使用して、DEFINE DATA ステートメント内でのみ定義できます。

level variable-name ( A ) DYNAMIC
level variable-name ( B ) DYNAMIC
level variable-name ( U ) DYNAMIC

制限事項:

以下の制限が、ダイナミック変数に適用されます。

  • ダイナミック変数は再定義できません。

  • ダイナミック変数は REDEFINE 節には使用できません。

ダイナミック変数の現在の値スペース

ダイナミック変数の現在の値スペースの長さ(コード単位)は、システム変数 *LENGTH から取得できます。*LENGTH は、割り当て時に自動的に、ソースオペランドの(使用されている)長さに設定されます。

注意:
パフォーマンスを考慮して、ダイナミック変数の値を保持するために割り当てられているストレージエリアが *LENGTH の値(プログラマが使用できるサイズ)より大きい場合があります。*LENGTH が示す使用長を超えて割り当てられているストレージは、対応するダイナミック変数にアクセスしていなくても解放される可能性が常にあるため、信頼しないでください。現在割り当てられているサイズに関する情報を取得する方法はありません。これは、内部値です。

*LENGTH(field) は、Natural のダイナミックフィールドまたはダイナミック変数の使用長(コード単位)を返します。A および B フォーマットでは、1 つのコード単位のサイズは 1 バイトです。U フォーマットでは、1 つのコード単位のサイズは 2 バイトです(UTF-16)。*LENGTH は、ダイナミック変数の現在の使用長を取得するためにのみ使用します。

サイズ制限チェック

プロファイルパラメータ USIZE

ダイナミック変数の場合、長さが定義されていないため、コンパイル時にサイズ制限チェックを行うことができません。ユーザーバッファエリアのサイズ(USIZE)は、仮想メモリ内のユーザーバッファのサイズを示します。ユーザーバッファには、Natural によってダイナミックに割り当てられているすべてのデータが含まれます。実行時にダイナミック変数の割り当てまたは拡張が行われて USIZE の制限を超えると、エラーメッセージが返されます。

ダイナミック変数のメモリスペースの割り当て/解放

ステートメント EXPANDREDUCE、および RESIZE は、ダイナミック変数のメモリスペースを明示的に割り当てたり解放したりするために使用します。

構文:

EXPAND [SIZE OF] DYNAMIC [VARIABLE]operand1 TOoperand2
REDUCE [SIZE OF] DYNAMIC [VARIABLE]operand1 TOoperand2
RESIZE [SIZE OF] DYNAMIC [VARIABLE]operand1 TOoperand2

- operand1 はダイナミック変数、operand2 は 0 以上の整数のサイズ値です。

EXPAND

関数

EXPAND ステートメントは、割り当てられているダイナミック変数(operand1)の長さを指定された長さ(operand2)に増やすために使用します。

指定されたサイズの変更

ダイナミック変数の現在の使用長(Natural システム変数 *LENGTH によって示される。上記参照)は変更されません。

指定された長さ(operand2)が、ダイナミック変数に割り当てられている長さに満たない場合、このステートメントは無視されます。

REDUCE

関数

REDUCE ステートメントは、割り当てられているダイナミック変数(operand1)の長さを指定された長さ(operand2)に減らすために使用します。

指定された長さ(operand1)を超える、ダイナミック変数(operand2)に割り当てられたストレージは、ステートメントの実行時または実行後に随時解放されます。

指定された長さの変更

ダイナミック変数の現在の使用長(Natural システム変数 *LENGTH によって示される。上記参照)が指定された長さ(operand2)を超えている場合、このダイナミック変数の *LENGTH は指定された長さに設定されます。変数の内容は切り捨てられますが、変更は行われません。

指定された長さが、現在割り当てられているダイナミック変数のストレージを超えている場合、このステートメントは無視されます。

RESIZE

関数

RESIZE ステートメントは、現在割り当てられているダイナミック変数(operand1)の長さを指定された長さ(operand2)に調整するために使用します。

指定された長さの変更

指定された長さが、ダイナミック変数の使用長(Natural システム変数 *LENGTH によって示される。上記参照)に満たない場合、必要に応じて、ダイナミック変数の使用長が縮小されます。

指定された長さが、現在割り当てられているダイナミック変数の長さを超えている場合、ダイナミック変数に割り当てられる長さが増やされます。システム変数 *LENGTH によって示される、ダイナミック変数の現在の使用長は影響を受けず、そのままになります。

指定された長さが、現在割り当てられているダイナミック変数の長さと同じ場合、RESIZE ステートメントを実行しても効力はありません。