コマンド
コマンドは、ObjectScript プログラミングの基本的なコード・ユニットです。ObjectScript の実行タスクは、すべてコマンドで実行されます。すべてのコマンドは、コマンド・キーワードと (ほとんどの場合) これに続く 1 つまたは複数のコマンド引数から構成されます。
この章では、ObjectScript コマンドの以下の側面について説明します。
この章では、次に ObjectScript コマンドの以下のグループについて簡単に説明します。
-
変数の割り当てを管理するコマンド — SET、KILL、および NEW
-
他のコマンドを実行するためのコンテキスト・コマンド — TRY および CATCH エラー処理構造。TSTART、TCOMMIT、および TROLLBACK トランザクション処理。LOCK リソース・ロック
-
コードの呼び出し (およびコードの終了) を行うコマンド — DO、JOB、および XECUTE。QUIT および RETURN
これは、ObjectScript コマンドの完全な一覧ではありません。これらおよび他の多くの ObjectScript コマンドについては、"Caché ObjectScript リファレンス" で詳しく説明しています。
コマンド・キーワード
ObjectScript では、すべてのコマンド文は明示的です。ObjectScript コードの実行可能行は、すべてコマンド・キーワードで始まる必要があります。例えば、変数に値を代入するには、SET キーワードを指定し、続いて変数の引数および代入する値を指定する必要があります。
コマンド・キーワードは、常にキーワードで始まります。以下の例を考えてみます。
WRITE "Hello"
“WRITE” という単語がコマンド・キーワードです。コマンドは、実行するアクションを指定します。WRITE コマンドは、その名前から分かるように、引数 として指定された内容を主デバイスに書き込みます。この場合、WRITE コマンドは文字列 “Hello” を書き込みます。
ObjectScript のコマンド名では、大文字と小文字は区別されません。ほとんどのコマンド名は省略形で表現できます。したがって、“WRITE”、“Write”、“write”、“W”、および “w” はいずれも、WRITE コマンドの有効な形式です。コマンドの省略形のリストは、"Caché ObjectScript リファレンス" の "省略形テーブル" を参照してください。
コマンド・キーワードは予約語ではありません。したがって、コマンド・キーワードを変数のユーザ割り当て名、ラベル、またはその他の識別子として使用できます。
ObjectScript プログラムでは、コード行の最初のコマンドをインデントにする必要があります。コマンド・キーワードは列 1 では使用できません。ターミナル・コマンド行プロンプトから、または XECUTE コマンドからコマンドを発行する場合、インデントは必要ありません (インデントにしてもかまいません)。
コードの実行可能行は、それぞれが独自のコマンド・キーワードを持つ 1 つまたは複数のコマンドを含むことができます。単一行における複数コマンドは 1 つ以上のスペースで区切ります。1 つ以上のコマンドは同一行のラベルの後に続きます。ラベルとコマンドは 1 つ以上のスペースで区切ります。
ObjectScript では、コマンド末端や行末の区切り文字が必要なく、または不許可となります。コマンドの後には、行内コメントを指定して、コマンド行の残りの部分がコメントであることを示すことができます。コマンドの末端とコメント構文の間には空白スペースが必要になりますが、##; および /* comment */ の構文については例外となります。/* comment */ の複数行コメントは、1 つのコマンド内かつコマンド末端にて指定可能です。
コマンド引数
コマンド・キーワードの後ろには、オブジェクト (複数も可) またはコマンドの範囲を指定する 1 つ以上の引数を置くことができます。 また、引数を置かない場合もあります。コマンドが 1 つ以上の引数を取得する場合、コマンド・キーワードと最初の引数の間にスペースを 1 つだけ置く必要があります。例えば以下のようになります。
SET x = 2
最初の引数の最初の文字が (上記のように) 正確に 1 つのスペースでコマンド自体から区切られている限り、引数内または引数間でスペースを使用できます。したがって、以下はすべて有効です。
SET a = 1
SET b=2
SET c=3,d=4
SET e= 5 , f =6
SET g
= 7
WRITE a,b,c,d,e,f,g
コマンドが 後置条件 を取る場合、コマンド・キーワードと後置条件間にスペースを置くことはできません。また、後置条件と 1 番目の引数の最初に必ず 1 つのスペースを置きます。以下の形式の QUIT コマンドはすべて有効です。
QUIT x+y
QUIT x + y
QUIT:x<0
QUIT:x<0 x+y
QUIT:x<0 x + y
引数間にスペースは必要ありませんが、複数の空白スペースを引数間で使用する場合もあります。これらの空白スペースは、コマンドの実行に影響を与えません。また、改行、タブ、コメントもコマンド引数内や引数間に含まれますが、コマンドの実行に影響はありません。詳細は、このドキュメントの “構文規則” の章の "空白" を参照してください。
複数の引数
多くのコマンドでは、複数の独立引数を指定することができます。コマンド引数の区切り記号はコンマ “,” です。つまり、1 つのコマンドの後ろに、コンマで区切られたリストとして複数の引数を指定します。例えば以下のようになります。
SET x=2,y=4,z=6
Set コマンドは、3 つの引数を使用して、指定した 3 つの変数に値を割り当てます。ここでは、複数の引数が繰り返されます。つまり、コマンドは、指定された順番で各引数に個別に割り当てられます。内部的には、Caché がこれを 3 つの別個 SET コマンドと解析します。デバッグ時においては、これらの複数の引数それぞれが別個の手順となります。
コマンド・リファレンス・ページで紹介しているコマンド構文では、繰り返して記述できる引数の後にコンマと省略記号 ,... が続きます。このコンマは引数に必要な区切り文字です。また、省略記号 (...) は、不特定の数の繰り返し引数を指定できることを示しています。
繰り返し引数は、厳密に左から右の順で実行されます。したがって、以下のコマンドが有効となります。
SET x=2,y=x+1,z=y+x
ただし、以下のコマンドは無効です。
SET y=x+1,x=2,z=y+x
各繰り返し引数は、指定した順序で独立して実行されるため、無効な引数が検出されるまで有効な引数が実行されます。以下の例では、SET x では値が x に代入され、SET y では <UNDEFINED> エラーが発生し、SET z が評価されていないため、<DIVIDE> (0 による除算) エラーは検出されません。
KILL x,y,z
SET x=2,y=z,z=5/0
WRITE "x is:",x
パラメータおよび後置条件付きの引数
いくつかのコマンド引数は、パラメータも受け取ります ("関数" で説明する関数パラメータと混同しないでください)。指定する引数がパラメータを取得できる場合、パラメータの区切り記号はコロン “:” です。
以下のコマンド例では、引数の区切り記号として使用されているコンマと、パラメータ区切り記号として使用されているコロンを示しています。ここでは、2 つの引数があり、各引数には 3 つのパラメータがあります。
VIEW X:y:z:a,B:a:y:z
少数のコマンド (DO、XECUTE、および GOTO) では、引数に続くコロンは、その引数を実行するかどうかを決める後置条件式を指定します。
引数なしコマンド
引数を持たないコマンドは、引数なし コマンドといいます。キーワードに追加された後置条件式は引数とはみなされません。
常に引数を持たないコマンドが少数あります。例えば、HALT、CONTINUE、TRY、TSTART および TCOMMIT は、引数なしコマンドです
いくつかのコマンドは必要に応じて引数なしになります。例えば、BREAK、CATCH、DO、FOR、GOTO、KILL、LOCK、NEW、QUIT、RETURN、TROLLBACK、WRITE、および ZWRITE には、すべて引数なしの構文形式があります。このような場合、同じコマンドでも引数ありと引数なしでは、意味が多少異なる場合があります。
引数なしコマンドを行の最後で使用する場合、末尾のスペースは必要ありません。引数なしコマンドを他のコマンドと同一のコード行で使用する場合、引数なしコマンドと後続のコマンドの間には 2 つ (あるいはそれ以上) のスペースを置く必要があります。例えば以下のようになります。
QUIT:x=10 WRITE "not 10 yet"
この場合、QUIT は後置条件式を持つ引数なしのコマンドです。このコマンドと次のコマンドの間に、少なくとも 2 つのスペースが必要です。
引数なしコマンドと中括弧
中括弧で区切られたコマンド・ブロック内で引数なしコマンドを使用する場合、空白の制限はありません。
-
引数なしコマンドの直後に左中括弧が続く場合、コマンド名と中括弧の間に空白は必要ありません。何も指定しないか、1 つあるいは複数のスペース、タブ、または改行を指定します。これは、FOR などのように引数を使用できる引数なしコマンド、および ELSE などのように引数を使用できない引数なしコマンドのどちらにも当てはまります。
FOR { WRITE !,"Quit out of 1st endless loop" QUIT } FOR{ WRITE !,"Quit out of 2nd endless loop" QUIT } FOR { WRITE !,"Quit out of 3rd endless loop" QUIT }
-
右中括弧は区切り文字として機能するため、引数なしコマンドの直後に右中括弧が続く場合、後続のスペースは必要ありません。例えば以下の方法で、引数なしの QUIT を使用します。
IF 1=2 { WRITE "Math error"} ELSE { WRITE "Arthmetic OK" QUIT} WRITE !,"Done"
コマンド後置条件式
ObjectScript のコマンドを使用する場合、後置条件を追加することができます。
後置条件とは、コマンドや (時には) コマンド引数に追加されるオプションの式で、Caché がそのコマンドやコマンド引数を実行するかどうかを制御します。後置条件式の評価が True (ゼロ以外の値) の場合、Caché はそのコマンドあるいはコマンド引数を実行します。また、評価が False (ゼロ) の場合、Caché はそのコマンドあるいはコマンド引数を実行せず、次のコマンドあるいはコマンド引数に実行を移します。
すべての ObjectScript コマンドでは、フロー制御コマンド (IF、ELSEIF、ELSE、FOR、WHILE、および DO WHILE) 以外、およびブロック構造エラー処理コマンド (TRY、THROW、CATCH) 以外で、後置条件式を使用できます。
ObjectScript コマンド DO と XECUTE は、コマンド・キーワードとコマンド引数の両方に後置条件式を追加できます。後置条件式は常にオプションです。例えば、コマンドの引数の中でも、後置条件式が追加されている引数と追加されていない引数があります。
コマンド・キーワードとコマンドの引数の両方が後置条件を持つ場合、キーワード後置条件が最初に評価されます。このキーワード後置条件が True に評価された場合にのみ、コマンド引数の後置条件が評価されます。コマンド・キーワードの後置条件が False の場合、コマンドは実行されず、プログラムは次のコマンドに移って実行を続けます。コマンド引数の後置条件が False の場合、引数は実行されず、コマンドは次の引数を左から右の順で実行を続けます。
後置条件構文
コマンドに後置条件を追加するには、コマンド・キーワードの直後にコロン (:) と式を置きます。後置条件式を持つコマンドの構文は以下のようになります。
Command:pc
Command はコマンド・キーワード、コロンは必須のリテラル文字で、pc は任意の有効な式にできます。
コマンド後置条件には、以下の構文規則があります。
-
スペース、タブ、改行、コメントは、コマンド・キーワードと後置条件式の間、あるいはコマンド引数と後置条件式の間には使用できません。コロン文字の前後にスペースを使用することはできません。
-
スペース、タブ、改行、コメントは、後置条件式内では使用できません。ただし、後置条件式全体が括弧で囲まれている場合や、括弧で囲まれた引数リストが後置条件式にある場合は使用できます。スペース、タブ、改行、コメントは括弧内で使用できます。
-
後置条件式の後に置く必要があるスペースは、コマンド・キーワードの場合と同様です。キーワード後置条件式の最後の文字と 1 番目の引数の最初の文字の間には、スペースを正確に 1 つ置きます。引数なしコマンドでは、後置条件の直後に右中括弧が続かない限り、後置条件式の最後の文字と同じ行にある次のコマンドの間に、2 つ以上のスペースを置く必要があります。(括弧を使用する場合、閉じ括弧は後置条件式の最後の文字として処理されます。)
後置条件式は、厳密に言えばコマンド引数ではありません (しかし、ObjectScript リファレンス・ページで、後置条件式は、引数セクションの一部として示されています)。後置条件は常にオプションです。
後置条件の評価
Caché は、後置条件式を True あるいは False と評価します。通常、これらは 1 あるいは 0 の値で評価することをお勧めします。しかし、Caché はあらゆる値の後置条件式を実行し、式の値が 0 の場合は False を、ゼロ以外の場合は True を返します。
-
Caché は、有効なゼロ以外の数値を True として評価します。算術演算のように、有効な数値に対し同じ評価基準を使用します。したがって、1、“1”、007、3.5、-.007、7.0、“3 little pigs”、$CHAR(49)、0_"1" はすべて、True と評価されます。
-
Caché はゼロ (0) 値、NULL 文字列 ("") や空白文字列 ("") などの非数値を False として評価します。したがって、0、-0.0、“A”、“-”、“$”、“The 3 little pigs”、$CHAR(0)、$CHAR(48)、"0_1" はすべて、False と評価されます。
-
一般的な Caché 等式の規則が適応されます。したがって、0=0、0="0"、"a"=$CHAR(97)、0=$CHAR(48)、(""=$CHAR(32)) は、True と評価されます。一方、0=""、0=$CHAR(0)、(""=$CHAR(32)) は False と評価されます。
次の例では、どの WRITE コマンドが実行されるかは、変数 count の値によって異なります。
FOR count=1:1:10 {
WRITE:count<5 count," is less than 5",!
WRITE:count=5 count," is 5",!
WRITE:count>5 count," is greater than 5",!
}
単一行での複数コマンド
ObjectScript のソース・コードの単一行には、複数のコマンドおよびそれらの引数を含めることができます。これらは厳密に左から右の順序で実行され、別々の行で記述したコマンドと機能的に同一となります。引数付きのコマンドは、単一の空白文字によって後続コマンドと区切る必要があります。引数なしのコマンドは、2 つの空白文字によって後続コマンドと区切る必要があります。ラベルには、同一行にて 1 つ以上のコマンドを後続させることができます。コメントは、同一行にて 1 つ以上のコマンドの後に続けることができます。
ソース・コードの行の最大長については、"Caché プログラミング入門ガイド" の付録 "一般的なシステム制限" を参照してください。スタジオを使用してソース・コードを記述/編集する場合、この制限は異なることがあります。
変数割り当てコマンド
変数の管理に必要な機能を提供するため、ObjectScript は以下のコマンドを備えています。
SET
SET コマンドは、変数に値を割り当てます。単一の変数または複数の変数に、一度に値を割り当てることができます。
以下は SET の基本的な構文です。
SET variable = expression
これにより、1 つの変数の値が設定されます。また、以下のようにいくつかの手順があります。
-
ObjectScript は、value 式を評価し、値を決定します (可能な場合)。この手順では、式に未定義変数、無効な構文 (例えばゼロによる除算)、他のエラーが含まれている場合、エラーを生成します。
-
変数が存在しない場合は、ObjectScript が変数を生成します。
-
一度変数が生成されると、あるいは変数が既に存在している場合、ObjectScript はその式の変数に値を設定します。
以下の構文を使用して、複数の変数それぞれに値を設定します。
SET variable1 = expression1, variable2 = expression2, variable3 = expression3
以下の構文を使用して、1 つの式と等しい複数の変数を設定します。
SET (variable1,variable2,variable3)= expression
例えば、以下のコードを使用して、Person クラス・インスタンスの Gender プロパティ値を設定します。
SET person.Gender = "Female"
ここで、person は、Person クラスの関連インスタンスへのオブジェクト参照です。
複数の Person オブジェクトの Gender プロパティを同時に設定することもできます。
SET (per1.Gender, per2.Gender, per3.Gender) = "Male"
ここで、per1、per2、per3 は、Person クラスの 3 つの異なるインスタンスへのオブジェクト参照です。
SET を使用して、値を返すメソッドを呼び出すことができます。メソッドを呼び出す場合、SET では、メソッドの返り値と同一の変数、グローバル参照、またはプロパティを設定できます。引数の形式は、メソッドが インスタンスかクラス・メソッド かどうかにより異なります。クラス・メソッドを呼び出すには、以下の構文を使用します。
SET retval = ##class(PackageName.ClassName).ClassMethodName()
ClassMethodName() は呼び出すクラス・メソッド名、ClassName はメソッドを含むクラス名、PackageName はクラスを含むパッケージ名です。メソッドの返り値は retval ローカル変数に割り当てられます。##class() 構文は、コードに必要なリテラル部です。
インスタンス・メソッドを呼び出すには、ローカルでインスタンスを生成されたオブジェクトへのハンドルのみが必要です。
SET retval = InstanceName.InstanceMethodName()
InstanceMethodName() は呼び出すインスタンス・メソッド名、InstanceName はメソッドを含むインスタンス名です。メソッドの返り値は retval ローカル変数に割り当てられます。
詳細は、"Caché ObjectScript リファレンス" の "SET" コマンドを参照してください。
KILL
KILL コマンドは、メモリから変数を削除し、また、ディスクからも削除できます。以下はその基本的な形式です。
KILL expression
expression は、削除する 1 つ以上の変数です。以下は、KILL の一番簡単な形式です。
KILL x
KILL x,y,z
“排他的 KILL” と呼ばれる KILL の特殊な形式は、指定された変数以外のすべてのローカル変数を削除します。排他的 KILL を使用するには、括弧内にその引数を置きます。例えば、変数 x、y、z がある場合、以下を実行して x 以外の y、z、または任意のローカル変数を削除できます。
KILL (x)
引数がない場合、KILL はすべてのローカル変数を削除します。
詳細は、"Caché ObjectScript リファレンス" の "KILL" コマンドを参照してください。
NEW
NEW コマンドは、新しいローカル変数のコンテキストを作成します。つまり、既存のローカル変数値を古いコンテキストに保存し、ローカル変数に値が代入されていない新しいコンテキストを開始します。プロシージャを使用するアプリケーションでは、NEW を使用して、アプリケーション全体、あるいはアプリケーションの主要なサブシステムの変数を初期化します。
以下の構文形式がサポートされます。
NEW // initiate new context for all local variables
NEW x // initiate new context for the specified local variable
NEW x,y,z // initiate new context for the listed local variables
NEW (y) // initiate new context for all local variables except the specified variable
NEW (y,z) // initiate new context for all local variables except the listed variables
詳細は、"Caché ObjectScript リファレンス" の "NEW" コマンドを参照してください。
コード実行コンテキスト・コマンド
以下のコマンドは、コマンドのグループの実行をサポートするために使用されます。
-
エラー処理のための TRY / CATCH ブロック構造。エラー処理のためにブロック構造を作成するには、TRY コマンドおよび CATCH コマンドを使用することをお勧めします。TRY ブロックには、目的の操作を実行する複数のコマンドが含まれています。各 TRY ブロックは、TRY ブロックでエラーが発生したときに呼び出される CATCH エラー処理ブロックと組み合わされています。各 TRY ブロックのすぐ後に、対応する CATCH ブロックが続く必要があります。複数の TRY / CATCH ブロックのペアを必要に応じてプログラムで作成できます。TRY / CATCH ブロックのペアを入れ子にすることも可能です。TRY ブロック内から THROW コマンドを使用して、対応する CATCH ブロックを明示的に呼び出すことができます。詳細は、このドキュメントの “エラー処理” の章の "TRY-CATCH メカニズム" を参照してください。"Caché ObjectScript リファレンス" の "TRY" コマンド、"THROW" コマンド、および "CATCH" コマンドを参照してください。
-
トランザクション処理用の TSTART コマンド、TCOMMIT コマンド、および TROLLBACK コマンド。(全か無かの単一のコード単位として) コマンドのグループをアトミックに実行する必要がある場合、コマンドのグループを TSTART コマンドで始め、 TCOMMIT コマンドで終えることをお勧めします。実行中に問題が発生した場合、TROLLBACK コマンドを発行して、コマンドのグループで実行された操作をロールバックする必要があります。詳細は "トランザクション処理" の章を参照してください。"Caché ObjectScript リファレンス" の "TSTART" コマンド、"TCOMMIT" コマンド、および "TROLLBACK" コマンドを参照してください。
-
リソースをロックまたはロック解除するための LOCK コマンド。詳細は "トランザクション処理" の章を参照してください。詳細は、"Caché ObjectScript リファレンス" の "LOCK" コマンドを参照してください。
コードの呼び出し
この節では、1 つまたは複数のコマンドの実行を呼び出すために使用するコマンドについて説明します。
DO
ObjectScript で任意のルーチン、プロシージャ、またはメソッドを呼び出すには、DO コマンドを使用します。以下は DO の基本的な構文です。
DO ^CodeToInvoke
CodeToInvoke は、Caché システム・ルーチンあるいはユーザ定義ルーチンです。キャレット文字 “^” は、ルーチン名の直前に付ける必要があります。
また、ルーチン内でプロシージャの開始場所を示すラベル (タグともいいます) を参照して、プロシージャを実行することもできます。ラベルは、キャレットの直前に置かれます。以下はその例です。
SET %X = 484
DO INT^%SQROOT
WRITE %Y
このコードは、%X システム変数値を 484 に設定します。その後 DO コマンドを使用して、Caché システム・ルーチン %SQROOT の INT プロシージャを呼び出し、%X の平方根を算出、%Y に格納します。その後、WRITE コマンドを使用して、%Y の値を表示します。
メソッドの呼び出し時、DO は 1 つの引数として、メソッドを指定する式全体を取得します。引数の形式は、メソッドが インスタンスかクラス・メソッド かどうかにより異なります。クラス・メソッドを呼び出すには、以下の構文を使用します。
DO ##class(PackageName.ClassName).ClassMethodName()
ClassMethodName() は呼び出すクラス・メソッド名、ClassName はメソッドを含むクラス名、PackageName はクラスを含むパッケージ名です。##class() 構文は、コードに必要なリテラル部です。
インスタンス・メソッドを呼び出すには、ローカルでインスタンスを生成されたオブジェクトへのハンドルのみが必要です。
DO InstanceName.InstanceMethodName()
InstanceMethodName() は呼び出すインスタンス・メソッド名、InstanceName はメソッドを含むインスタンス名です。
詳細は、"Caché ObjectScript リファレンス" の "DO" コマンドを参照してください。
JOB
DO はフォアグラウンドでコードを実行し、JOB はバックグラウンドで実行します。これは、通常ユーザとの対話なしに、現在のプロセスで単独に実行されます。ジョブ起動プロセスは、明示的に指定された場合を除き、すべてのシステムの既定値を継承します。
詳細は、"Caché ObjectScript リファレンス" の "JOB" コマンドを参照してください。
XECUTE
XECUTE コマンドは、1 つ以上の ObjectScript コマンドを実行し、引数として取得する式を評価します (その引数は、1 つ以上の ObjectScript コマンドを含む文字列に評価される必要があります)。実際、各 XECUTE 引数は、DO コマンドによって呼び出される一行サブルーチンに類似しており、引数の最後に達するか、QUIT コマンドに遭遇すると終了します。Caché が引数を実行した後、制御は XECUTE 引数の直後に返されます。
詳細は、"Caché ObjectScript リファレンス" の "XECUTE" コマンドを参照してください。
QUIT および RETURN
QUIT コマンドと RETURN コマンドは、両方ともメソッドを含むコード・ブロックの実行を終了させます。引数がない場合、呼び出し元のコードを単に終了します。引数がある場合、返り値としてその引数を使用します。QUIT は、現在のコンテキストを終了し、囲んでいるコンテキストに移動します。RETURN は、現在のプログラムを終了し、プログラムが呼び出された場所に移動します。
以下のテーブルは、QUIT を使用するか RETURN を使用するかを選択する方法を示しています。
Location | QUIT | RETURN |
---|---|---|
ルーチン・コード (ブロック構造になっていない) | ルーチンを終了し、呼び出し元のルーチン (存在する場合) に戻ります。 | ルーチンを終了し、呼び出し元のルーチン (存在する場合) に戻ります。 |
TRY または CATCH ブロック | TRY / CATCH ブロック構造のペアを終了し、ルーチンの次のコードに移動します。入れ子にされた TRY または CATCH ブロックから発行された場合、1 レベルを終了し、囲んでいる TRY または CATCH ブロックに移動します。 | ルーチンを終了し、呼び出し元のルーチン (存在する場合) に戻ります。 |
DO または XECUTE | ルーチンを終了し、呼び出し元のルーチン (存在する場合) に戻ります。 | ルーチンを終了し、呼び出し元のルーチン (存在する場合) に戻ります。 |
IF | ルーチンを終了し、呼び出し元のルーチン (存在する場合) に戻ります。ただし、FOR、WHILE、または DO WHILE ループで入れ子にされている場合、そのブロック構造を終了し、コード・ブロックの後の次の行で続行します。 | ルーチンを終了し、呼び出し元のルーチン (存在する場合) に戻ります。 |
FOR、WHILE、DO WHILE | ブロック構造を終了し、コード・ブロックの後の次の行で続行します。入れ子にされたブロックから発行された場合、1 レベルを終了し、囲んでいるブロックに移動します。 | ルーチンを終了し、呼び出し元のルーチン (存在する場合) に戻ります。 |
詳細は、"Caché ObjectScript リファレンス" の "QUIT" コマンドおよび "RETURN" コマンドを参照してください。
フロー制御コマンド
コードでロジックを構築するためには、フロー制御が必要です。コードのブロックを条件付きで実行するかまたはバイパスするか、またはコードのブロックを繰り返し実行します。そのために、ObjectScript は以下のコマンドをサポートします。
条件付きの実行
コードのブロックを条件付きで実行するには、ブーリアン (True/False) テストに基づいて、IF コマンドを使用できます。(後置条件式を使用して、個別の ObjectScript コマンドの条件付きの実行を行うことができます。)
IF は、式を引数として取得し、式が True か False かを判断します。True の場合、式の後ろに続くコードのブロックが実行され、False の場合は実行されません。通常、これらは 1 あるいは 0 の値で評価することをお勧めします。しかし、Caché はあらゆる値の条件付きの実行を行い、式の値が 0 の場合は False を、ゼロ以外の場合は True を返します。詳細は、このドキュメントの "演算子と式" の章を参照してください。
複数の IF ブーリアン・テスト式を、コンマ区切りのリストで指定することができます。これらのテストは、一連の論理 AND テストとして左から順に評価されます。したがって、IF は、すべてのテスト式が True に評価されると、True に評価されます。IF は、テスト式の 1 つが False と評価されると False に評価されます。残りのテスト式は評価されません。
コードは、常に多数のコマンドを含む コード・ブロック で表示されます。コード・ブロックとは、単に { } 括弧内の 1 行以上のコード行のことで、コード・ブロックの前と中には改行を置くことができます。以下の例を考えてみます。
IF、ELSEIF、および ELSE
IF 文は、複数の条件を評価し、条件によってどのコードを実行するのかを指定できます。単純なコマンドと異なり、文とは 1 つ以上のコマンド・キーワード、条件式、コード・ブロックを含みます。IF 文は、以下のものから構成されます。
-
1 つまたは複数の条件式を含む 1 つの IF 節。
-
それぞれが 1 つまたは複数の条件式を含む任意の数の ELSEIF 節。ELSEIF 節 (オプション)。ELSEIF 節は複数でもかまいません。
-
条件式のない、1 つ以下の ELSE 節。ELSE 節は、オプションです。
以下は、IF 文の例です。
READ "Enter the number of equal-length sides in the polygon: ",x
IF x=1 {WRITE !,"It's so far away that it looks like a point"}
ELSEIF x=2 {WRITE !,"I think that's a line, not a polygon"}
ELSEIF x=3 {WRITE !,"It's an equalateral triangle"}
ELSEIF x=4 {WRITE !,"It's a square"}
ELSE {WRITE !,"It's a polygon with ",x," number of sides" }
WRITE !,"Finished the IF test"
詳細は、"Caché ObjectScript リファレンス" の "IF" コマンドを参照してください。
FOR
FOR 文を使用すると、コードのセクションを繰り返し実行できます。数値や文字列値を基に FOR ループを生成できます。
通常、FOR は、コードのそれぞれのループの開始でインクリメントあるいはディクリメントされる数値制御変数の値を基に、コード・ブロックを 0 回以上実行します。制御変数が最後の値に達したとき、制御は FOR ループを終了します。終了値がない場合、ループは QUIT コマンドに遭遇するまで実行を続けます。制御がループを終了すると、制御変数は、最後のループの実行による値を保持します。
以下は、数値 FOR ループの形式です。
FOR ControlVariable = StartValue:IncrementAmount:EndValue {
// code block content
}
すべての値は正数あるいは負数で、スペースは許可されていますが、等符号とコロンの前後には不要です。FOR に続くコード・ブロックは、変数に割り当てられた各値を繰り返します。
例えば、以下の FOR ループは 5 回実行します。
WRITE "The first five multiples of 3 are:",!
FOR multiple = 3:3:15 {
WRITE multiple,!
}
また、変数を使用して、最後の値を決めることもできます。以下の例は、ループが繰り返される回数を指定します。
SET howmany = 4
WRITE "The first ",howmany," multiples of 3 are "
FOR multiple = 1:1:howmany {
WRITE (multiple*3),", "
IF multiple = (howmany - 1) {
WRITE "and "
}
IF multiple = howmany {
WRITE "and that's it!"
}
}
QUIT
この例は、制御変数 multiple を使用して 3 倍しているため、式は multiple*3 となります。また、IF コマンドを使用して、最後の計算の前に “and” を挿入しています。
この例の IF コマンドは、ObjectScript の優先順位を含む分かりやすい例です (優先順位は、階層に関係なく常に左から右です)。IF 式 “multiple = howmany - 1” の括弧がない場合、あるいは全体が括弧で囲まれている場合、式の最初の部分 “multiple = howmany” は、False (0) となります。 したがって、式全体は “0 - 1” となり、結果は -1 であるため、この式は True となります (ループで、最後の繰り返し以外、それぞれの文字列に “and” を挿入します)。
FOR の引数は、値のリストに設定された変数にすることもできます。この場合、コード・ブロックは、変数に割り当てられたリストで、各項目に対して繰り返します。
FOR b = "John", "Paul", "George", "Ringo" {
WRITE !, "Was ", b, " the leader? "
READ choice
}
QUIT コマンドを特定の状況で実行されるようコード・ブロック内に配置し、FOR を終了させるように指定すると、最終値のない FOR の数値形式を記述できます。これにより、繰り返し回数を示すカウンタを提供し、カウンタの値に基づかない条件を使用して、FOR を制御できます。例えば、以下のループはカウンタを使用し、推測された回数をユーザに知らせます。
FOR i = 1:1 {
READ !, "Capital of MA? ", a
IF a = "Boston" {
WRITE "...did it in ", i, " tries"
QUIT
}
}
カウンタが不要な場合、引数なしの FOR を使用できます。
FOR {
READ !, "Know what? ", wh
QUIT:(wh = "No!")
WRITE " That's what!"
}
詳細は、"Caché ObjectScript リファレンス" の "FOR" コマンドを参照してください。
WHILE と DO WHILE
2 つの関連するフロー制御コマンド、WHILE と DO WHILE は、それぞれがコード・ブロックでループを実行し、条件に応じて終了します。2 つのコマンドは、条件の評価方法が異なります。WHILE はコード・ブロック全体の前に条件を評価し、DO WHILE はブロックの後に条件を評価します。FOR と同様、コード・ブロック内に QUIT コマンドを記述してループを終了します。
2 つのコマンドの構文は、以下のとおりです。
DO {code} WHILE condition
WHILE condition {code}
以下の例は、ユーザが指定した値までフィボナッチの数列で値を 2 回表示します (最初は DO WHILE 次はWHILE を使用)。
fibonacci() PUBLIC { // generate Fibonacci sequences
READ !, "Generate Fibonacci sequence up to where? ", upto
SET t1 = 1, t2 = 1, fib = 1
WRITE !
DO {
WRITE fib," " set fib = t1 + t2, t1 = t2, t2 = fib
}
WHILE ( fib '> upto )
SET t1 = 1, t2 = 1, fib = 1
WRITE !
WHILE ( fib '> upto ) {
WRITE fib," "
SET fib = t1 + t2, t1 = t2, t2 = fib
}
}
WHILE、DO WHILE、FOR の明確な違いは、WHILE はループの実行前、DO WHILE はループの実行後に制御式の値をテストする必要があり、一方 FOR はループ内ならどこででもテストできる点です。つまり、コード・ブロックに 2 つの部分があり、式の評価によって 2 番目を実行する場合、FOR 文が一番適切です。それ以外の場合、式をコード・ブロックの前か後のいずれに評価するかによって選択します。
詳細は、"Caché ObjectScript リファレンス" の "WHILE" コマンドおよび "DO WHILE" コマンドを参照してください。
入出力コマンド
ObjectScript の入出力コマンドは、Caché の内部あるいは外部でデータを取得する基本的な機能を提供します。以下のとおりです。
表示 (書き込み) コマンド
ObjectScript は、現在の出力デバイスにリテラルと変数値を表示 (書き込み) する、以下の 4 つのコマンドをサポートしています。
引数なしの表示コマンド
-
引数なしの WRITE は、定義済みの各ローカル変数の名前と値を表示します (行ごとに 1 つの変数を表示します)。パブリック変数とプライベート変数の両方がリスト表示されます。グローバル変数、プロセス・プライベート・グローバルまたは特殊変数はリスト表示されません。変数は照合シーケンス順でリスト表示されます。添え字ツリー順で添え字付き変数をリストします。
すべてのデータ値は、二重引用符文字で区切られ、引用符で囲まれた文字列として表示されます。ただし、キャノニック形式の数とオブジェクト参照を除きます。オブジェクト参照 (OREF) 値が割り当てられた変数は、variable=<OBJECT REFERENCE>[oref] として表示されます。%List 形式の値またはビット文字列の値は、引用符で囲まれた文字列として、それらの値がエンコードされた形式で表示されます。このようなエンコードされた形式には非表示文字が含まれている可能性があるため、%List やビット文字列の表示は空の文字列になることがあります。
WRITE は、特定の非表示文字を表示しません。そうした非表示文字を表現するための、プレースホルダやスペースは表示されません。WRITE は、制御文字を実行します (改行やバックスペースなど)。
-
引数なしの ZWRITE は、引数なしの WRITE と同様に機能します。
-
引数なしの ZZDUMP は、無効なコマンドであり、<SYNTAX> エラーを生成します。
-
引数なしの ZZWRITE は、空の文字列を返す空命令です。
引数ありの表示コマンド
以下の表に、4 つのコマンドの引数付きの形式の機能をリストします。4 つのすべてのコマンドは、1 つの引数または引数のコンマ区切りリストを取ります。4 つのすべてのコマンドは、引数として、ローカル変数、グローバル変数またはプロセス・プライベート変数、リテラル、式、または特殊変数を取ります。
以下の表には、%Library.Utility.FormatString()Opens in a new tab メソッドの既定の戻り値も示されています。FormatString() メソッドは、ZZWRITE とほとんど同じですが、戻り値の一部として %val= をリスト表示しないことと、オブジェクト参照 (OREF) 識別子のみを返す点が異なります。FormatString() を使用すると、ZWRITE/ZZWRITE 形式の戻り値に変数を設定できるようになります。
WRITE | ZWRITE | ZZDUMP | ZZWRITE | FormatString() | |
---|---|---|---|---|---|
各値を別個の行に表示 | なし | あり | あり (1 行に 16 文字) | あり | 1 つの入力値のみ |
識別された変数名 | なし | あり | なし | %val= で表される | なし |
未定義の変数を <UNDEFINED> エラーと表示 | あり | なし (スキップされ、変数名は返されない) | あり | あり | あり |
4 つのすべてのコマンドは、式を評価して、キャノニック形式で数値を返します。
WRITE | ZWRITE | ZZDUMP | ZZWRITE | FormatString() | |
---|---|---|---|---|---|
16 進表現 | なし | なし | あり | なし | なし |
文字列を囲む引用符 (数値と区別するため) | なし | あり | なし | あり (文字列リテラルは %val="value" として返される) | あり |
添え字ノードの表示 | なし | あり | なし | なし | なし |
別のネームスペースのグローバル変数 (拡張グローバル参照) の表示 | あり | あり (拡張グローバル参照構文が示される) | あり | あり | あり |
非表示文字の表示 | なし、表示されない (制御文字は実行される) | あり、$c(n) として表示される | あり、16 進数として表示される | あり、$c(n) として表示される | あり、$c(n) として表示される |
リスト値の形式 | エンコードされた文字列 | $lb(val) 形式 | エンコードされた文字列 | $lb(val) 形式 | $lb(val) 形式 |
%Status 形式 | エンコードされたリストを含んでいる文字列 | $lb(val) 形式のリストを含んでいる文字列、エラーとメッセージを明示する /*... */ コメントが付加される。 | エンコードされたリストを含んでいる文字列 | $lb(val) 形式のリストを含んでいる文字列、エラーとメッセージを明示する /*... */ コメントが付加される。 | $lb(val) 形式のリストを含んでいる文字列、エラーとメッセージを明示する /*... */ コメントが付加される (既定の場合)。 |
ビット文字列形式 | エンコードされた文字列 | $zwc 形式、1 つのビットをリストする /* $bit() */ コメントが付加される。例: %val=$zwc(407,2,1,2,3,5)/*$bit(2..4,6)*/ | エンコードされた文字列 | $zwc 形式、1 つのビットをリストする /* $bit() */ コメントが付加される。例: %val=$zwc(407,2,1,2,3,5)/*$bit(2..4,6)*/ | $zwc 形式、1 つのビットをリストする /* $bit() */ コメントが付加される (既定の場合)。例: %val=$zwc(407,2,1,2,3,5)/*$bit(2..4,6)*/ |
オブジェクト参照 (OREF) 形式 | OREF のみ | <OBJECT REFERENCE>[oref] 形式の OREF。一般情報や属性値などの詳細がリストされる。すべてのサブノードがリストされる | OREF のみ | <OBJECT REFERENCE>[oref] 形式の OREF。一般情報や属性値などの詳細がリストされる。 | OREF のみ (引用符で囲まれた文字列形式) |
JSON の動的配列と JSON のダイナミック・オブジェクトは、該当するコマンドのすべてで OREF 値として返されます。JSON のコンテンツを返すには、以下の例に示すように、%ToJSON() を使用する必要があります。
SET jobj={"name":"Fred","city":"Bedrock"}
WRITE "JSON object reference:",!
ZWRITE jobj
WRITE !!,"JSON object value:",!
ZWRITE jobj.%ToJSON()
詳細は、"Caché ObjectScript リファレンス" の "WRITE"、"ZWRITE"、"ZZDUMP"、および "ZZWRITE" の各コマンドを参照してください。
READ
READ コマンドを使用すると、現在の入力装置からエンド・ユーザが入力した内容を受け取り、格納することができます。READ コマンドは、以下の引数を持つことができます。
READ format, string, variable
format は、ユーザの入力エリアが画面に表示される場所を制御し、string は入力プロンプトの前に画面に表示され、variable は入力データを格納します。
以下の形式コードを使用して、ユーザ入力エリアを制御します。
形式コード | 結果 |
---|---|
! | 新しい行を開始します。 |
# | 新しいページを開始します。ターミナルでは、現在の画面をクリアして、新規画面の一番上から開始します。 |
?n | n 番目の列に移動します。n は正の整数です。 |
詳細は、"Caché ObjectScript リファレンス" の "READ" コマンドを参照してください。
OPEN、USE、および CLOSE
さらに高度なデバイス処理を実行するために、Caché は多彩なオプションを提供します。つまり、OPEN コマンドでデバイスを開き、USE コマンドで現在のデバイスを指定して、CLOSE コマンドで実行中のデバイスを閉じることができます。この処理の詳細は、"Caché 入出力デバイス・ガイド" で説明されています。
詳細は、"Caché ObjectScript リファレンス" の "OPEN" コマンド、"USE" コマンド、および "CLOSE" コマンドを参照してください。