DO (従来のバージョン)
Synopsis
DO:pc . blockcommand . blockcommand nextcommand
引数
pc | オプション — 後置条件式 |
blockcommand | コード・ブロックとして実行される 1 つまたは複数の ObjectScript コマンド。ブロックでは、各コマンドの文頭に必ずピリオド (.) が付くことに注意してください。コメントや空白の行にも必ず、文頭にピリオドが付きます。 |
nextcommand | DO コード・ブロックの後に続く ObjectScript コマンド。これは、先頭にピリオドが付いていない引数なしの DO の後の、最初のコード行です。 |
説明
このページでは、従来の引数なしの DO コマンドについて説明します。DO コマンドの引数なしのバージョンは、Caché 4.0 時点で従来のバージョンと見なされるもので、新規のプログラムでは使用すべきではありません。ここでは、従来のアプリケーションとの互換性について説明します。
従来の引数なし DO コマンドは、コード・ブロック内でコード行をまとめるために、文頭のピリオドを使用します。{ } 括弧は使用されず、行フォーマット化の使用は制限されます。現在、この構文の代わりに使用されているのは、{ } 構文です。IF や FOR コマンドでは、引数なしの DO は現在は使用されておらず、DO:pc 演算の代わりにブロック構造の IF コマンドが使用されています。この構文は { } 構文とは互換性がありません。したがって、{ } 構文を使用する IF や FOR など現在の Caché ブロック構造コマンドは、引数なしの DO コード・ブロックでは使用されないこともあります。
引数なしの DO コマンドは、プログラム内の DO コマンドの直後に続くコード・ブロックを実行します。引数なしの DO ブロックは入れ子にでき、DO コマンドの後置条件式を使用して、コード・ブロックを実行するかどうかを決定できます。
つまり Caché は、DO コマンドの直後に続くコード・ブロックを実行し、その後、コード・ブロックの次のコマンドを実行します。
引数なしの DO コマンドで実行されるコード行は、特別なブロック構造の構文で記述する必要があります。この構文は、ピリオド (.) でコード行を開始します。このブロック構造構文は、引数なしの DO コマンドでのみ使用されます。
後置条件式で、引数なしの DO コマンドを指定することができます。後置条件式が False (0) をテストする場合、Caché は後続のコード・ブロック (およびその内部の入れ子にされたコード・ブロック) を即座に飛ばし、DO コマンドと同じ行レベルで実行を開始します。
引数なしの DO ブロック構造
ブロック構造は、引数なし DO コマンドの直後に続くので、プログラムが読みやすく、維持しやすくなります。一般的に、一度だけ呼び出される短いルーチン、およびブロック構造を使用しないとコード全体に広がる可能性があるルーチンを置き換えるためにブロック構造を使用します。ブロック構造は、関連する DO コマンドの後に配置すると見つけやすくなります。構文のレベルを明白にすると、コードを読みやすくすることができます。
ブロック構造は、1 つ、または複数のコード・ブロックで構成されており、各ブロックは同じ入れ子レベルで 1 つ、または複数の行で成り立っています。同じレベルにあるすべての行は、コード行の先頭に同数のピリオド (.) があるため、他のレベルと区別できます。
コード・ブロック構文
コード・ブロックに属する行を示すために使用されるピリオド (.) は、以下の構文を使用します。
-
引数なしの DO コマンドは、コード行での最後のコマンドになります。このコマンドの後の 1 つかそれ以上の空白文字の後には、同じ行にコメント文字 (; または、//) が続きます。
-
引数なしの DO コマンド直後のコード行と、コード・ブロック内の各行の先頭には、それがコメント行、あるいは空白行の場合でも、ピリオドを配置する必要があります。
-
ピリオドは、コード行の文頭に配置されます。したがって、コマンドやコメントはコード行で、ピリオドの前、またはピリオドの間に現れることはありません。
-
ピリオドはインデントしなければなりません。したがって、コード行の第 1 列目にピリオドを記述することはできません。通常、最初のピリオドは引数なしの DO コマンドを含むコード行と同じレベルにインデントされています。
-
入れ子にされたコード・ブロックは、ピリオドを文頭に追加することで、入れ子の各レベルをマークします。入れ子を示すために、最も外側の DO を含むコード行のレベルに最初のピリオドを配置し、入れ子のレベルを追加するごとにピリオドを追加してインデントします。
-
コード・ブロックはラベルを含むことはできません。コード・ブロックにコメント行や空白の行を含むことはできますが、これらの行の文頭にはピリオドを配置する必要があります。
-
ピリオドは、最低でも 1 つの空白文字 (スペースあるいはタブ) を後に配置する必要があります。
-
この空白文字の後には、コマンド・キーワード、他の文頭のピリオド (.)、コメント指示子 (; または //)、および改行のいずれかが続きます。したがって、コマンドの改行は、この構文では使用されません。
-
ピリオドが先頭にあるコード・ブロックは、{ } 括弧で表されたコード・ブロックとは結合できません。
入れ子
ピリオドが先頭にあるコード・ブロックは、ブロック同士を入れ子にできます。コード・ブロックに属する行の先頭にはすべて同数のピリオドがあるため、各ブロックのコンテンツを視覚的に識別できます。
リスト表示したとき、入れ子にされたコード・ブロックの行はインデントして表示されます。例えば、内側のブロック行の先頭にあるピリオド数は、外側のブロック内の行数よりも 1 つ多くなります。
ブロックが終了するとき、現在の行より先頭のピリオドが少ない行によって示されるように、ObjectScript はコード・ブロックを終了する暗黙の QUIT を発行して、前のレベルで実行を再開します。ブロックの最後の行に、明示的な QUIT コマンドを記述できますが、これは必須ではありません。
変数
すべてのコード・ブロックは、同じローカル変数を共有します。したがって、そのコード・ブロック・レベルを呼び出す前に、変数を設定して内側のブロックに値を渡すことができます。同様に、内側のブロックの実行結果は、共有されているローカル変数値を変更することで、次の上位レベルに保存できます。
$TEST 特殊変数は、サブルーチンやプロシージャを呼び出す引数なしの DO によって、サブルーチンやプロシージャを呼び出す DO コマンドとは異なる方法で処理されます。引数なしの DO コマンドは、コード・ブロックの実行中に $TEST の初期値を保存します。ブロックに $TEST 値を再設定するコマンド (例えば従来の IF コマンド、または時間が決められた OPEN) が含まれている場合、この変更は次の上位レベルには渡されません。
QUIT コマンド
引数なし DO コード・ブロック内で QUIT コマンドを発行した場合、Caché は、その直後のコード・ブロックを終了し、これに続く次のコマンドに移って実行を続けます。
以下の例では、この QUIT の動作を示します。
DO
. WRITE "into the DO",!
. DO
.. WRITE "inner DO",!
.. QUIT
.. WRITE "never written",!
. WRITE "back to outer DO",!
. QUIT
. WRITE "never written",!
WRITE "out of the DO"
引数
pc
オプションの後置条件式です。Caché は、後置条件式が True (0 以外の数値) の場合にこのコマンドを実行します。Caché は、後置条件式が False (0) の場合はコマンドを実行しません。詳細は、"Caché ObjectScript の使用法" の "コマンド後置条件式" を参照してください。
blockcommand
コード・ブロックとして実行される 1 つまたは複数の ObjectScript コマンド。各 blockcommand 行 (コメントや空白の行も含む) の先頭には、コード・ブロック構文で指定されたように 1 つ、または複数のピリオドが含まれている必要があります。
例
以下の例は、従来のバージョンの IF コマンドおよび FOR コマンドを使用していることに注意してください。(IF と FORの現在のバージョンのように) { } 括弧を使用したコード・ブロックに記述されたコマンドは、引数なしの DO コマンドを使用する必要はなく、また、文頭にピリオドがある構文との互換性もありません。
以下の例は、2 つの引数なし DO コマンドのそれぞれが、ブロック・コードを呼び出します。どちらの DO コマンドが呼び出され、その後どちらのブロックが呼び出されるかは、IF コマンドの指定に従い、ユーザが要求する操作により決定します。いずれの場合においても、結果は共有された同じローカル変数から WRITE コマンドに渡されます。最初のブロック (整数の 2 乗値を計算) には暗黙の QUIT が含まれ、一方、2 番目のブロック (整数の 3 乗値を計算) には明示的な QUIT が含まれます。
Start ; Square or cube an integer.
READ !,"Square (S) or cube (C): ",op QUIT:op=""
READ !,"Integer: ",num QUIT:num=""
IF (op["S")!(op["s") DO
. SET result=num*num ; Square block
. WRITE !,"Result: ",result
ELSE DO
. SET result=num*num*num ; Cube block
. WRITE !,"Result: ",result
. QUIT
GOTO Start
以下の例では、引数なしの DO が FOR 制御変数 (i) が y の値と等しくなるまで、コード・ブロックを繰り返し実行します。
FOR i=1:1:y DO
. SET z=z*x
. WRITE !,z
. QUIT
以下の例は、暗黙の QUIT コマンドを使用して各ブロックを終了する、ObjectScript 内の入れ子にされたコード・ブロックを示します。
MyRoutine ; Routine label
WRITE !,"At top level" ; Mainline code (Level count = 0)
DO
. ; Outermost block (Level count = 1)
.
. DO
. . ; Inner block 1 (Level count = 2)
. .
. . DO
. . . ; Inner block 2 (Level count = 3)
. . .
. . ; (Level count = 2)
. ; (Level count = 1)
.
. QUIT ; (Level count = 0)
WRITE !,"Back at top level" ; Mainline code resumes
これまでの例で示してきたように、最初の引数なし DO は最も外側のコード・ブロックにある行の実行を開始します。ObjectScript は、DO が存在する行レベルを保存します。ObjectScript が後続の引数なしの DO コマンドを検出した場合、1 つ内側のコード・ブロックを実行し、行レベルを 1 つインクリメントします。ブロック内で明示的な、または暗黙の QUIT を検出すると、ObjectScript は行レベルを 1 つデクリメントし、そのブロックの DO に続くコマンドで実行を継続します。