Skip to main content

従来の形式のサブルーチン

ルーチンには、一般的な意味でのサブルーチンという用語を使用して、複数のサブルーチンを含めることができます。作成する新しいルーチンには、プロシージャを定義することをお勧めします。既存のコードでは、他の形式のサブルーチンを目にすることがあります。このページでは、これらの他の形式について、および必要に応じてこれらを呼び出す方法について説明します。

従来の形式の認識

従来の形式のサブルーチンは、ラベルを使用しますが、中括弧では囲まれません。参照用に、以下のリストに、使用可能な構文とその仮名を示します。いずれの場合でも、label はコード・ユニットの識別子、args は引数リスト、オプションの scopekeywordPublic または Private のいずれかです。

サブルーチン

正式には、真のサブルーチンとは、以下の形式のコード・ユニットです (一般的な意味でのサブルーチンとは異なります)。

label(args) scopekeyword
	  //implementation
  QUIT

"サブルーチン" を参照してください。

外部関数

正式には、真の外部関数とは、以下の形式のコード・ユニットです (システム定義の ObjectScript 内部関数とは異なります)。

label(args) scopekeyword
	  //implementation
  QUIT optionalreturnvalue

サブルーチンとは異なり、関数は値を返します。"関数" を参照してください。

これらの従来の形式では、サブルーチンや関数の実行が終了すると、これらの中で定義された変数が利用可能になります。そのため、これらの従来の形式では、異なる手法 (具体的には NEW コマンドと KILL コマンド) を使用して変数の範囲を管理します。

サブルーチン

構文

サブルーチン構文 :

label [ ( param [ = default  ][ , ...] ) ] 
   code
   QUIT 

以下の構文で呼び出します。

DO label [ ( param [ , ...]  ) ] 

または

GOTO label 
引数 説明
label サブルーチンの名前標準ラベルです。必ず 1 列目から始まります。label の後に続くパラメータの括弧はオプションです。パラメータが指定されたサブルーチンは、GOTO では呼び出されません。パラメータの括弧は、直前に実行されるコードがサブルーチン内に “フォールスルーする” のを防ぎます。InterSystems IRIS は、パラメータの括弧付きラベルに遭遇した場合 (中身が空でも)、暗黙の QUIT を実行し、ルーチンの次の行に実行が移らないように実行を終了します。
param 呼び出し元のプログラムからサブルーチンに渡されるパラメータの値。GOTO コマンドを使用して呼び出されるサブルーチンは、param 値を持つことはできず、パラメータの括弧を使うこともできません。DO コマンドを使用して呼び出されるサブルーチンには、param 値があってもなくてもかまいません。param 値がない場合、空のパラメータの括弧は記述しても省略してもかまいません。サブルーチンに必要な各パラメータに対し、param 変数を指定します。必要なパラメータは、仮パラメータ・リストと呼ばれます。このリストには、何も指定しなくても、1 つ以上の param を定義してもかまいません。複数の param 値がある場合、コンマによって区切られます。InterSystems IRIS は、参照された param 変数に対して、自動的に NEW を呼び出します。パラメータは、値または参照によって渡されます。
default 直前の param に対するオプションの既定値です。各パラメータに対して既定値を提供しても、省略してもかまいません。仮パラメータに対応する実パラメータが指定されていない場合、または実パラメータが参照渡しされたときに当該のローカル変数に値がない場合は、既定値が適用されます。この既定値はリテラル、つまり引用符で囲まれた数字あるいは文字列です。null 文字列 ("") も既定値として指定できます。null 文字列は変数を定義するため、これは既定値を指定しないこととは異なります。一方でパラメータ値が未指定の場合や既定値がない場合、変数は未定義となります。リテラル以外の既定値を指定すると、InterSystems IRIS は <PARAMETER> エラーを発行します。
code コード・ブロックです。コード・ブロックは、通常ラベルを呼び出してアクセスします。しかし、コード・ブロック内で別のラベルを呼び出したり、label + offset の GOTO コマンドを使用しても入力 (再入力) できます。コード・ブロックでは、他のサブルーチン、関数、プロシージャを入れ子にして呼び出すことができます。入れ子になった呼び出しは、リンクされた一連の GOTO コマンドではなく、DO コマンドまたは関数呼び出しを使用して実行することをお勧めします。コード・ブロックは、通常、明示的な QUIT コマンドで終了します。必須ではありませんが、QUIT コマンドの記述をお勧めします。外部ラベルに GOTO を使用して、サブルーチンを終了することもできます。

説明

サブルーチンは、最初の行の 1 列目にあるラベルで識別されるコード・ブロックです。サブルーチンの実行は、通常、明示的な QUIT 文によって終了します。

サブルーチンは、DO コマンドまたは GOTO コマンドで呼び出します。

  • DO コマンドはサブルーチンを実行し、その後、呼び出し元のルーチンの実行を再開します。したがって、InterSystems IRIS がサブルーチンで QUIT コマンドに遭遇した場合、呼び出し元のルーチンに戻り、DO コマンドに続く次の行を実行します。

  • GOTO コマンドは、サブルーチンを実行しますが、呼び出し元のプログラムに制御を戻しません。InterSystems IRIS は、サブルーチンの中で QUIT コマンドに遭遇したときに実行を終了します。

DO コマンドで呼び出されたサブルーチンにパラメータを渡すことができますが、GOTO コマンドで呼び出されたサブルーチンには渡せません。値、もしくは参照によってパラメータを渡せます。"引数の引き渡し" を参照してください。

サブルーチンと呼び出し元のルーチンは、同じ変数を使用できます。

サブルーチンは値を返しません。

関数

関数は既定でプロシージャ (推奨) となります。ただし、プロシージャではない関数を定義することも可能です。このセクションでは、このような関数について説明しています。

構文

以下はプロシージャではない関数の構文です。

label ( [param [ = default  ]] [ , ...] ) 
   code
   QUIT expression 

以下の構文で呼び出します。

command $$label([param[ ,...]]) 

または

DO label([param[ ,...]]) 
引数 説明
label 関数名。標準ラベルです。必ず 1 列目から始まります。label に続くパラメータの括弧は必須です。
param 関数に必要な各パラメータの変数です。必要なパラメータは、仮パラメータ・リストと呼ばれます。このリストには、何も指定しなくても、1 つ以上の param を定義してもかまいません。複数の param 値がある場合、コンマによって区切られます。InterSystems IRIS は、参照された param 変数に対して、自動的に NEW を呼び出します。パラメータは、値または参照によって渡されます。
default 直前の param に対するオプションの既定値です。各パラメータに対して既定値を提供しても、省略してもかまいません。仮パラメータに対応する実パラメータが指定されていない場合、または実パラメータが参照渡しされたときに当該のローカル変数に値がない場合は、既定値が適用されます。この既定値はリテラル、つまり引用符で囲まれた数字あるいは文字列です。null 文字列 () も既定値として指定できます。null 文字列は変数を定義するため、これは既定値を指定しないこととは異なります。一方でパラメータ値が未指定の場合や既定値がない場合、変数は未定義となります。リテラル以外の既定値を指定すると、InterSystems IRIS は <PARAMETER> エラーを発行します。
code コード・ブロックです。コード・ブロックでは、他のサブルーチン、関数、プロシージャを入れ子にして呼び出すことができます。入れ子になった呼び出しは、DO コマンドまたは関数呼び出しで実行する必要があります。GOTO コマンドでは、関数のコード・ブロックを終了できません。コード・ブロックは、式を持つ明示的な QUIT コマンドを使用してのみ終了できます。
expression 有効な ObjectScript 式で指定される関数返り値です。式を持つ QUIT コマンドは、ユーザ定義関数では必須です。式から生じる値は、関数の結果として呼び出し元に返されます。

説明

このセクションでは、ユーザ定義関数について説明します。ユーザ定義関数の呼び出しは、接頭語 $$ で識別されます。(ユーザ定義関数は、外部関数ともいいます。)

ユーザ定義関数により、InterSystems IRIS が提供する関数に新たな関数を追加できます。通常、どのプログラムからでも呼び出せる汎用的な処理を実装するために関数を使用します。

関数は、常に ObjectScript コマンドから呼び出されます。式として評価され、呼び出し元のコマンドに単一の値を返します。以下に例を示します。

 SET x=$$myfunc()

従来のコードとラベル

プロシージャはラベルと中括弧で定義され、これらによって実装がカプセル化されます。一方、このページで示す従来の形式のサブルーチンの場合、コードの自動カプセル化は行われません。つまり、ラベルはエントリ・ポイントを提供しますが、カプセル化されたコード・ユニットを定義しません。これは、ラベル付けされたコードが実行されれば、実行が停止またはリダイレクトされない限り、次のラベル付けされたコード・ユニットへと実行が続くことを意味します。コード・ユニットの実行を停止するには、以下の 3 つの方法があります。

  • コード実行が QUIT または RETURN に遭遇する。

  • コード実行が TRY の閉じ中括弧に (“}”) に遭遇する。これが発生すると、関連付けられた CATCH ブロックに続くコードの次の行へと実行を継続します。

  • コード実行が次のプロシージャ・ブロック (パラメータの括弧付きラベル) に遭遇する。括弧付きラベル行と遭遇すると、括弧内にパラメータがない場合においても、実行が停止します。

以下の例では、label0 以下から label1 以下までコードが連続して実行されます。

  SET x = $RANDOM(2)
  IF x=0 {DO label0
           WRITE "Finished Routine0",! }
  ELSE {DO label1
           WRITE "Finished Routine1",! }
  QUIT
label0
  WRITE "In Routine0",!
  FOR i=1:1:5 {
      WRITE "x = ",x,!
      SET x = x+1 }
  WRITE "At the end of Routine0",!
label1
  WRITE "In Routine1",!
  FOR i=1:1:5 {
      WRITE "x = ",x,!
      SET x = x+1 }
  WRITE "At the end of Routine1",!

以下の例では、ラベル付けされたコード・セクションが QUIT または RETURN コマンドのいずれかで終了します。これによって実行が止まります。RETURN は常に実行を止めて、QUIT は現在のコンテキストの実行を止めることに注意してください。

  SET x = $RANDOM(2)
  IF x=0 {DO label0
           WRITE "Finished Routine0",! }
  ELSE {DO label1
           WRITE "Finished Routine1",! }
  QUIT
label0
  WRITE "In Routine0",!
  FOR i=1:1:5 {
      WRITE "x = ",x,!
      SET x = x+1
      QUIT }
  WRITE "Quit the FOR loop, not the routine",!
  WRITE "At the end of Routine0",!
  QUIT
  WRITE "This should never print"
label1
  WRITE "In Routine1",!
  FOR i=1:1:5 {
      WRITE "x = ",x,!
      SET x = x+1 }
  WRITE "At the end of Routine1",!
  RETURN
  WRITE "This should never print"

以下の例では、2 番目と 3 番目のラベルがプロシージャ・ブロック (パラメータの括弧にて指定されたラベル) を指定します。プロシージャ・ブロックのラベルと遭遇すると、実行が停止します。

  SET x = $RANDOM(2)
  IF x=0 {DO label0
           WRITE "Finished Routine0",! }
  ELSE {DO label1
           WRITE "Finished Routine1",! }
  QUIT
label0
  WRITE "In Routine0",!
  FOR i=1:1:5 {
      WRITE "x = ",x,!
      SET x = x+1 }
  WRITE "At the end of Routine0",!
label1()
  WRITE "In Routine1",!
  FOR i=1:1:5 {
      WRITE "x = ",x,!
      SET x = x+1 }
  WRITE "At the end of Routine1",!
label2()
  WRITE "This should never print"
FeedbackOpens in a new tab