Skip to main content

This documentation is for an older version of this product. See the latest version of this content.Opens in a new tab

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 オプション — 呼び出されるルーチンに渡されるパラメータ値。

説明

Note:

DODO 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 をデクリメントし、NEWSET $ZTRAP の操作を元に戻します。

現在のルーチン

ターミナルから DO を呼び出した場合、DO は最初に、現在ロードされているルーチンを検索します。現在のプロセスに現在のルーチンがある場合は、DO は、ディスク上の対応するルーチンではなく、この現在のルーチンを実行します。

例えば、ZLOAD コマンドを使用して、ディスクからルーチン myroutine をロードするとします。これにより、このルーチンが現在のルーチンになります ($ZNAME 特殊変数で表示されます)。その後、ZINSERT を使用して現在のルーチンを変更してから、DO ^myroutine を呼び出します。DO コマンドで実行されるのは、ディスク上の変更されていない myroutine ではなく、変更された myroutine です。引数なしの ZREMOVE コマンドで、現在ロードされているルーチンをアンロードします。引数なしの ZREMOVE の後に DO ^myroutine を実行すると、ディスクから、変更されていないバージョンの myroutine が実行されます。

現在のルーチンは、以下の 2 つの方法のいずれかで呼び出すことができます。

  • 明示的なルーチン名を使用する。DO ^myroutineDO Label2^myroutine、または DO Label2+3^myroutine のようになります。

  • 暗黙的なルーチン名を使用して、ラベルとオフセット (オプション) を指定する。DO MainDO 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 を使用する場合は、呼び出し元のルーチンと呼び出されるサブルーチンが同じ変数を参照していることを確認する必要があります。

Note:

プロシージャによる変数の処理は、まったく異なります。"ObjectScript の使用法" の "プロシージャ" を参照してください。

以下の例では、Start (呼び出し元のルーチン) と Exponent (呼び出されるサブルーチン) が 3 つの変数 numpowr、および result へのアクセスを共有しています。Start では、numpowr がユーザ指定の値に設定されます。これらの値は、Exponent が DO コマンドによって呼び出されたときに、自動的に Exponent でも利用できます。Exponent は、numpowr を参照し、計算した値を 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 呼び出しの間も保存するためには、その呼び出しの前に、この値を明示的に変数に代入します。その後、呼び出しが続くコードで変数を参照できます。

関連項目

FeedbackOpens in a new tab