DO (ObjectScript)
Synopsis
DO:pc doargument,... D:pc doargument,...
doargument には、以下を指定できます。
entryref(param,...):pc
引数
引数 | 説明 |
---|---|
pc | オプション — 後置条件式。 |
entryref | 呼び出されるルーチンの名前。ルーチン名の前にはキャレットが付きます (DO ^myroutine)。オプションで、ラベル名 (DO Label2^myroutine) や、ラベルと行オフセット (DO Label2+3^myroutine) を指定します。現在のルーチンを呼び出す場合は、ルーチン名を省略して、ラベル、またはラベルと行オフセットのみを指定できます。以下に示すように、DO oref.Method() としてオブジェクト・メソッドを呼び出したり、別の構文形式を使用したりすることもできます。 |
param | オプション — 呼び出されるルーチンに渡されるパラメータ値。 |
説明
DO と DO WHILE は異なる無関係のコマンドです。ここでは、DO コマンドについて説明します。DO WHILE コマンドでは、DO キーワードと WHILE キーワードは、複数のコード行によって分割されています。しかし、DO キーワードの後には左中括弧が続くので DO WHILE コマンドの識別は簡単です。
DO コマンドは、特定のオブジェクト・メソッド、サブルーチン、関数、またはプロシージャを呼び出します。InterSystems IRIS は、呼び出されたルーチンを実行し、DO コマンドの次のコマンドを実行します。ルーチンの呼び出しでは、パラメータは渡しても渡さなくてもかまいません。例えば、DO ^myrou1 または DO ^myrou(a,b,c) となります。
DO は呼び出されたルーチンからの戻り値を受け取れません。呼び出されたルーチンが引数付きの QUIT で終了している場合、DO コマンドは正常に終了しますが、QUIT の引数値は無視されます。
DO では、複数の引数を、コンマ区切りのリストで指定することができます。例えば、DO ^myrou1,^myrou2,^myrou3 となります。引数は指定した順序で実行されます。無効な引数が見つかった場合、実行は停止します。
DO は、通常、既存のコンパイル済みルーチンを実行する場合にターミナル・プロンプトで呼び出します。もちろん、ルーチンの内部から DO コマンドを呼び出すこともできます。
DO の各呼び出しは、新しいコンテキスト・フレームをプロセスのコール・スタックに配置します。$STACK 特殊変数は、コール・スタックのコンテキスト・フレームの現在の番号を含みます。このコンテキスト・フレームは、新しい実行レベルを作成して、$STACK と $ESTACK をインクリメントし、DO の実行中に発行された NEW および SET $ZTRAP の操作のスコープを提供します。正常に終了すると、DO は $STACK と $ESTACK をデクリメントし、NEW と SET $ZTRAP の操作を元に戻します。
現在のルーチン
ターミナルから DO を呼び出した場合、DO は最初に、現在ロードされているルーチンを検索します。現在のプロセスに現在のルーチンがある場合は、DO は、ディスク上の対応するルーチンではなく、この現在のルーチンを実行します。
例えば、ZLOAD コマンドを使用して、ディスクからルーチン myroutine をロードするとします。これにより、このルーチンが現在のルーチンになります ($ZNAME 特殊変数で表示されます)。その後、ZINSERT を使用して現在のルーチンを変更してから、DO ^myroutine を呼び出します。DO コマンドで実行されるのは、ディスク上の変更されていない myroutine ではなく、変更された myroutine です。引数なしの ZREMOVE コマンドで、現在ロードされているルーチンをアンロードします。引数なしの ZREMOVE の後に DO ^myroutine を実行すると、ディスクから、変更されていないバージョンの myroutine が実行されます。
現在のルーチンは、以下の 2 つの方法のいずれかで呼び出すことができます。
-
明示的なルーチン名を使用する。DO ^myroutine、DO Label2^myroutine、または DO Label2+3^myroutine のようになります。
-
暗黙的なルーチン名を使用して、ラベルとオフセット (オプション) を指定する。DO Main、DO Label2、または DO Label2+3 のようになります。
引数
pc
オプションの後置条件式です。後置条件式が DO コマンド・キーワードに追加されている場合、InterSystems IRIS は後置条件式が True (0 以外の数値に評価される) の場合に DO コマンドを実行します。後置条件式が False (0 に評価される) の場合、InterSystems IRIS は DO コマンドを実行しません。
後置条件式が引数に追加されている場合、InterSystems IRIS は後置条件式が True (0 以外の数値に評価される) の場合に引数を実行します。後置条件式が False (0 に評価される) の場合、InterSystems IRIS はその引数をスキップし、次の引数 (存在する場合) もしくは次のコマンドの評価に進みます。次に、例を示します。
DO:0 $INCREMENT(myvar($INCREMENT(subvar))):1 /* myvar and subvar not incremented */
DO:1 $INCREMENT(myvar($INCREMENT(subvar))):0 /* myvar not incremented, subvar incremented */
InterSystems IRIS は左から右へ式を処理するため、後置条件式が評価される前に、式を含む引数部分 (パラメータ値、オブジェクト参照など) が評価され、エラーが発生する場合があります。後置条件式を追加して DO でオブジェクト・メソッドを呼び出す場合、オブジェクト・メソッド・パラメータの最大個数は 253 です。
詳細は、"ObjectScript の使用法" の "コマンド後置条件式" を参照してください。
entryref
呼び出すルーチン (オブジェクト・メソッド、サブルーチン、プロシージャ、またはユーザ指定関数) の名前。複数のルーチンを、コンマ区切りのリストで指定することができます。
entryref は以下のすべての形式で指定できます。
entryref 形式 | 説明 |
---|---|
label+offset | 現在のルーチン内の行ラベルを指定します。オプションの +offset は、パラメータを渡されていないサブルーチンを呼び出すためにだけ使用します。プロシージャの呼び出し、もしくはサブルーチンへパラメータを渡すためには使用できません。offset は負でない整数で、ラベルの何行後からサブルーチンの実行を開始するかを指定します。 |
label+offset^routine | ディスクに保存されている指定したルーチン内の行ラベルを指定します。InterSystems IRIS は、ディスクからそのルーチンをロードし、指定されたラベルから実行を開始します。+offset はオプションです。 |
^routine | ディスクにあるルーチンの名前。システムは、ディスクからそのルーチンをロードし、そのルーチン内の最初の実行可能行から実行を開始します。リテラル値である必要があります。変数は、routine の指定には使用できません。(^ 文字は区切り文字で、ルーチン名の一部ではないことに注意してください。) ルーチンが変更されている場合、DO がそのルーチンを呼び出すときに、InterSystems IRIS は更新バージョンのルーチンをロードします。ルーチンが現在のネームスペースにない場合、拡張ルーチン参照を使用して、ルーチンを含むネームスペースを ^|"namespace"|routine のように指定できます。 |
oref.Method() |
オブジェクト・メソッドを指定します。システムはオブジェクトにアクセスして、指定したメソッドを実行します。(存在する場合は) param で指定した引数とメソッドの引数リストを渡します。オブジェクトの呼び出しは、ドット構文を使用します。oref (オブジェクト参照) と Method() は、ドットで区切られます。空白スペースは許可されません。param 引数がない場合でも、開き括弧と閉じ括弧は必要です。 サポートされている構文形式は、DO oref.Method()、DO (oref).Method()、DO ..Method()、DO ##class(cname).Method()、DO i%prop(subs).Method() です。 |
IRISSYS % ルーチンの呼び出し時における offset の指定はできません。指定しようとすると、InterSystems IRIS は <NOLINE> エラーを発行します。
存在しないラベルを指定した場合、InterSystems IRIS は <NOLINE> エラーを返します。存在しないルーチンを指定した場合、InterSystems IRIS は <NOROUTINE> エラーを返します。存在しないメソッドを指定した場合、InterSystems IRIS は <METHOD DOES NOT EXIST> エラーを返します。既存のプロパティを (括弧で囲んで) メソッドとして指定した場合、InterSystems IRIS は <OBJECT DISPATCH> エラーを返します。拡張参照 (例えば、DO ^|"%SYS"|MyProg) を使用して、存在しないネームスペースを指定した場合、InterSystems IRIS は <NAMESPACE> エラーを返します。拡張参照を使用して、特権を持たないネームスペースを指定した場合、InterSystems IRIS は <PROTECT> エラーを返し、続けてデータベース・パスを表示します (例 : <PROTECT> *^|^^c:\intersystems\iris\mgr\|MyRoutine)。これらのエラーの詳細は、"$ZERROR" 特殊変数を参照してください。
複数行の構文中を指す offset を指定すると、システムでは次の構文の最初で実行を開始します。
param
サブルーチン、プロシージャ、ユーザ指定関数、またはオブジェクト・メソッドに渡されるパラメータ値です。単一の param 値、あるいはコンマで区切られたparam 値のリストを指定できます。param リストは、括弧で囲まれます。param が指定されていない場合、プロシージャ、ユーザ指定関数、またオプションでサブルーチンを呼び出す際に括弧が必要です。パラメータは、値または参照によって渡されます。同じ呼び出しで、値渡しによるパラメータと参照渡しによるパラメータを混合して指定できます。値渡しの場合、パラメータを値定数、式、または添え字なしのローカル変数名として指定できます。("値渡し" を参照してください。)参照渡しの場合、パラメータは、ローカル変数の名前、または .name. という形式の添え字なしの配列を参照する必要があります (詳細は "参照渡し" を参照してください)。
1 つの DO エントリポイントの param 値の最大合計数は 382、1 つの DO メソッドまたは DO 間接演算の param 値の最大合計数は 380 です。この合計には、最大で 254 の実パラメータと 128 の後置条件パラメータを含めることができます。
... 構文を使用して可変個数のパラメータを指定できます。
DO コマンドの entryref 引数
entryref 引数付きの DO コマンドは、1 つまたは複数の定義済みのコード・ブロックの実行を呼び出します。実行する各コード・ブロックは、entryref で指定されます。DO コマンドは、コンマで区切られたリストとして、実行する複数のコード・ブロックを指定できます。DO コマンドの実行とコンマで区切られたリストにある各 entryref の実行は、オプションの後置条件式で管理できます。
DO は、(パラメータ付き、あるいはパラメータなしの) サブルーチン、プロシージャ、ユーザ指定関数の実行を呼び出します。ブロック・コードの実行が終了した場合、DO コマンドの直後のコマンドで再開します。DO コマンドで呼び出されたコード・ブロックは、DO コマンドに値を返すことはできません。返された値はいずれも無視されます。したがって、DO はユーザ指定関数を実行しますが、関数の返り値の取得はできません。
DO は、ほとんどの ObjectScript のシステム関数を呼び出すことができません。呼び出しを試みると、<SYNTAX> エラーが返されます。いくつかのシステム関数を DO コマンドの引数として呼び出すことができます:$CASE、$CLASSMETHOD、$METHOD、$INCREMENT、および $ZF(-100)。DO は関数の返り値を受け取ることはできません。すべての DO コマンド引数と同様に、これらの関数は後置条件パラメータを取ることができます。例えば、次のようになります。DO $CASE(exp,0:NoMul(),2:Square(num),3:Cube(num),:Exponent(num,exp)):0プログラム例については、"$CASE" 関数を参照してください。
パラメータ渡しなしの DO コマンド
パラメータ渡しなしの DO コマンドは、サブルーチンと一緒の場合にのみ使用されます。DO entryref にパラメータを渡さない (つまり、param オプションを指定しない) で使用すると、呼び出し元のルーチンとそれによって呼び出されたサブルーチンで、同じ変数環境が共有されるという事実を利用できます。サブルーチンにより変数の更新が行われた場合、これらはすべて自動的に DO コマンドの後のコードで使用可能となります。
パラメータを渡さずに DO を使用する場合は、呼び出し元のルーチンと呼び出されるサブルーチンが同じ変数を参照していることを確認する必要があります。
以下の例では、Start (呼び出し元のルーチン) と Exponent (呼び出されるサブルーチン) が 3 つの変数 num、powr、および result へのアクセスを共有しています。Start では、num と powr がユーザ指定の値に設定されます。これらの値は、Exponent が DO コマンドによって呼び出されたときに、自動的に Exponent でも利用できます。Exponent は、num と powr を参照し、計算した値を result に代入します。Exponent が RETURN コマンドを実行する場合、制御は DO の後の WRITE コマンドに即座に戻ります。WRITE コマンドは、result を参照して計算された値を出力します。
Start ; Raise an integer to a specified power.
READ !,"Integer= ",num QUIT:num=""
READ !,"Power= ",powr QUIT:powr=""
DO Exponent()
WRITE !,"Result= ",result,!
RETURN
Exponent()
SET result=num
FOR i=1:1:powr-1 { SET result=result*num }
RETURN
以下の例で、DO は pat によって参照されるオブジェクトで、Admit() メソッドを呼び出します。このメソッドはパラメータを受け取らず、また値も返しません。
DO pat.Admit()
以下の例では、DO が、現在のルーチン内の Init サブルーチンと Read1 サブルーチン、および Test ルーチン内の Convert サブルーチンを連続して呼び出します。
DO Init,Read1,Convert^Test
以下の例では、DO は拡張参照を使用して、別のネームスペース (SAMPLES ネームスペース) の fibonacci ルーチンを呼び出しています。
NEW $NAMESPACE
SET $NAMESPACE="USER"
DO ^|"SAMPLES"|fibonacci
DO と GOTO
DO コマンドを使用して、(パラメータ付き、あるいはなしの) サブルーチン、プロシージャ、ユーザ指定関数を呼び出します。呼び出しの終了時、InterSystems IRIS は DO コマンドに続く次のコマンドを実行します。
GOTO コマンドは、パラメータ渡しなしのサブルーチンを呼び出すためにのみ使用します。呼び出しの終了時、InterSystems IRIS は QUIT を呼び出し、実行を終了します。
パラメータ渡しの DO
パラメータ渡しが使用される場合、DO entryref は、呼び出したサブルーチン、プロシージャ、ユーザ指定関数、またはオブジェクト・メソッドに 1 つ、または複数の値を明示的に渡します。渡す値は、コンマで区切られたリストとして param オプションで指定されたものです。パラメータ渡しを行う場合は、呼び出されるサブルーチンがパラメータ・リスト付きで定義されているかを確認する必要があります。サブルーチンの定義の形式は、以下のとおりです。
>label( param)
label では、サブルーチン、プロシージャ、ユーザ指定関数、またはオブジェクト・メソッドのラベル名を指定します。param では、コンマで区切られた添え字なしのローカル変数名 1 つ、または複数からなるリストを指定します。以下はその例です。
Main
SET x=1,y=2,z=3
WRITE !,"In Main ",x,y,z
DO Sub1(x,y,z)
WRITE !,"Back in Main ",x,y,z
QUIT
Sub1(a,b,c)
WRITE !,"In Sub1 ",a,b,c
QUIT
DO コマンドで渡されるパラメータ・リストは、実パラメータ・リスト (実リスト) と呼ばれます。コード化されたルーチン・ラベルの一部として定義されるパラメータ変数のリストは、仮パラメータ・リスト (仮リスト) と呼ばれます。DO コマンドがルーチンを呼び出すとき、実リストのパラメータは、その位置に従って、仮リスト内の対応する変数にマップされます。上述の例では、1 番目の実パラメータ (x) の値は、サブルーチンの仮パラメータ・リストにある 1 番目の変数 (a) に代入され、2 番目の実パラメータ (y) の値は 2 番目の変数 (b) に代入されます。その後、サブルーチンは、仮パラメータ・リストの変数を参照することによって、渡された値にアクセスできます。
実パラメータ・リスト内の変数が、仮パラメータ・リスト内のパラメータよりも多い場合、InterSystems IRIS は <PARAMETER> エラーを発行します。
仮リスト内の変数が、実リスト内のパラメータよりも多い場合は、余った変数は未定義のままになります。以下の例は、仮パラメータ c が未定義のままになっています。
Main
SET x=1,y=2,z=3
WRITE !,"In Main ",x,y,z
DO Sub1(x,y)
WRITE !,"Back in Main ",x,y,z
QUIT
Sub1(a,b,c)
WRITE !,"In Sub1 "
IF $DATA(a) {WRITE !,"a=",a}
ELSE {WRITE !,"a is undefined"}
IF $DATA(b) {WRITE !,"b=",b}
ELSE {WRITE !,"b is undefined"}
IF $DATA(c) {WRITE !,"c=",c}
ELSE {WRITE !,"c is undefined"}
QUIT
実パラメータ値が指定されていない場合、仮パラメータに対し既定値を指定できます。
DO コマンドの実パラメータ・リストから、対応するパラメータを削除して、変数を未定義のままにできます。ただし、実パラメータを削除した個所に、プレースホルダとしてコンマを入れる必要があります。以下の例は、仮パラメータ b が未定義のままになっています。
Main
SET x=1,y=2,z=3
WRITE !,"In Main ",x,y,z
DO Sub1(x,,z)
WRITE !,"Back in Main ",x,y,z
QUIT
Sub1(a,b,c)
WRITE !,"In Sub1 "
IF $DATA(a) {WRITE !,"a=",a}
ELSE {WRITE !,"a is undefined"}
IF $DATA(b) {WRITE !,"b=",b}
ELSE {WRITE !,"b is undefined"}
IF $DATA(c) {WRITE !,"c=",c}
ELSE {WRITE !,"c is undefined"}
QUIT
... 構文を使用して、可変個数のパラメータを指定できます。
Main
SET x=3,x(1)=10,x(2)=20,x(3)=30
DO Sub1(x...)
QUIT
Sub1(a,b,c)
WRITE a," ",b," ",c
QUIT
DO コマンドは、パラメータの値渡し (DO Sub1(x,y,z) など)、または参照渡し (DO Sub1(.x,.y,.z) など) のいずれかを行います。同じ DO コマンド内で、値渡しと参照渡しを混合して指定することもできます。詳細は、"ObjectScript の使用法" の "パラメータ渡し" を参照してください。
以下の例は、値渡しと参照渡しの違いを示しています。
Main /* Passing by Value */
SET x=1,y=2,z=3
WRITE !,"In Main ",x,y,z
DO Sub1(x,y,z)
WRITE !,"Back in Main ",x,y,z
QUIT
Sub1(a,b,c)
SET a=a+1,b=b+1,c=c+1
WRITE !,"In Sub1 ",a,b,c
QUIT
Main /* Passing by Reference */
SET x=1,y=2,z=3
WRITE !,"In Main ",x,y,z
DO Sub1(.x,.y,.z)
WRITE !,"Back in Main ",x,y,z
QUIT
Sub1(&a,&b,&c) /* The & prefix is an optional by-reference marker */
SET a=a+1,b=b+1,c=c+1
WRITE !,"In Sub1 ",a,b,c
QUIT
間接指定の DO
間接指定を使用して、DO にターゲットのサブルーチンの場所を提供することができます。例えば、さまざまなメニュー関数を別のルーチン内の異なる場所に組み込む方法で、一般的なメニュー・プログラムを実装するとします。メイン・プログラム・コードで、名前による間接指定を使用して、DO コマンドにメニューの各選択項目に対応するサブルーチンの場所を提供することができます。
InterSystems IRIS オブジェクト・ドット構文を使用して、間接指定をすることはできません。ドット構文が実行時ではなく、コンパイル時に構文解析されるためです。
名前による間接指定の場合、間接指定演算子 (@) の右側の式の値が名前 (行ラベル またはルーチン) でなければなりません。以下のコード部分では、名前による間接指定によって、DO コマンドに Menu ルーチン内のターゲット・サブルーチンの場所が提供されています。
READ !,"Enter the number for your choice: ",num QUIT:num=""
DO @("Item"_num)^Menu
DO コマンドは、Menu 内のサブルーチンを呼び出します。このサブルーチンのラベルは、Item とユーザ指定の num 値が連結されたもの (Item1、Item2 など) です。
間接指定の引数形式を使用して、完全な DO 引数の代わりに、式の値を使用することもできます。例えば、以下の DO コマンドを見てみましょう。
DO @(eref_":fstr>0")
このコマンドは、fstr の値が 0 より大きい場合に、eref の値で指定されたサブルーチンを呼び出します。
詳細は、"ObjectScript の使用法" の "間接演算" を参照してください
引数後置条件付きの DO
DO コマンドのターゲット・サブルーチンを選択するには、引数後置条件式を使用できます。後置条件式が False (0) で評価される場合、InterSystems IRIS は関連付けられているサブルーチン呼び出しを無視します。後置条件式が True (1) で評価される場合、InterSystems IRIS は関連付けられているサブルーチン呼び出しを実行してから、DO コマンドに戻ります。DO コマンドの引数とその引数の両方で、後置条件を使用できます。
例えば、以下のコマンドを考えてみます。
DO:F>0 A:F=1,B:F=2,C
DO コマンドには後置条件式があり、F が 0 以下の場合、DO は実行されません。DO コマンドの引数にも、後置条件式があります。DO は後置条件のこれらの引数を使用して、実行するサブルーチン (A、B、C) を選択します。True 条件を満たすすべてのサブルーチンが、指定されている順番に実行されます。つまり、この例では、後置条件式のない C は常に実行されます。F が 1 の場合は A と C が実行され、F が 2 の場合は B とC が実行され、F が 3 (または他の任意の数) の場合は C が実行されます。True の既定として C を指定する場合は、次のようにします。
DO:F>0 A:F=1,B:F=2,C:((F'=1)&&(F'=2))
この例では、実行されるサブルーチンは 1 つのみになります。
以下の例で、DO コマンドは後置条件式を取り、その引数もそれぞれ後置条件式を取ります。この場合、最初の引数は後置条件式が 0 であるため、実行されません。2 つ目の引数は後置条件式が 1 であるため実行されます。
Main
SET x=1,y=2,z=3
WRITE !,"In Main ",x,y,z
DO:1 Sub1(x,y,z):0,Sub2(x,y,z):1
WRITE !,"Back in Main ",x,y,z
QUIT
Sub1(a,b,c)
WRITE !,"In Sub1 ",a,b,c
QUIT
Sub2(d,e,f)
WRITE !,"In Sub2 ",d,e,f
QUIT
DO によって呼び出されるオブジェクト (oref) メソッドのほとんどは、引数後置条件式を取ることができます。ただし、$SYSTEM オブジェクト・メソッドは、引数後置条件式を取ることができません。これを実行しようとすると、<SYNTAX> エラーが生成されます。
InterSystems IRIS では、式は必ず左から右の順番で評価されるため、引数後置条件式が評価される前に、式を含む引数が評価されます (エラーが生成される場合もあります)。
引数の後置条件を使用するときは、副作用がないことを確認してください。例えば、以下のコマンドを考えてみます。
DO @^Control(i):z=1
この場合 ^Control(i) には、後置条件 z=1 が True の場合に呼び出すサブルーチンの名前が含まれています。z=1 であるかどうかにかかわらず、InterSystems IRIS は ^Control(i) の値を評価し、それに従って、現在のグローバル・ネイキッド・インジケータを再設定します。z=1 が False の場合、InterSystems IRIS は DO を実行しません。ただし、グローバル・ネイキッド・インジケータは、DO を実行したかのようにリセットされます。ネイキッド・インジケータに関する詳細は、"グローバルの使用法" の "ネイキッド・グローバル参照" を参照してください。
後置条件式の評価方法に関する詳細は、"ObjectScript の使用法" の "コマンド後置条件式" を参照してください。
DO を使用した場合の $TEST の振る舞い
DO を使用してプロシージャを呼び出すと、InterSystems IRIS では $TEST の値を保持します。これは、プロシージャを終了するときの呼び出し時に、値をその状態にリストアすることで保持されます。ただし、DO を使用してサブルーチンを呼び出す場合 (パラメータを渡す場合も渡さない場合も) は、その呼び出しの間、InterSystems IRIS では $TEST の値は保存しません。
$TEST 値を DO 呼び出しの間も保存するためには、その呼び出しの前に、この値を明示的に変数に代入します。その後、呼び出しが続くコードで変数を参照できます。