Skip to main content

間接 (@)

名前、パターン、コマンド引数、配列ノード、または $TEXT 引数の構文を、間接オペランドの値を通じて間接的に含めることができます。

間接演算の概要

ObjectScript の間接演算子 (@) により、コマンド行、コマンド、またはコマンド引数の一部またはすべてを実行時に動的に置き換えることができます。InterSystems IRIS® データ・プラットフォームは、関連するコマンドを実行する前に、置換を実行します。

間接演算は、添え字間接演算の場合を除いて、間接演算子 (@) で指定され、以下の形式になります。

@variable

variable は、置換する値の取得元の変数です。変数は配列ノードにできます。間接演算子を使用するための手順は次の 2 つです。

  1. 値を variable に割り当てます。適切な値は、意図したコンテキストによって異なります。

    置換する値で参照されるすべての変数は、プロシージャで使用されているとしてもパブリック変数であることに注意してください。

  2. 該当するコンテキストに (つまり、コマンド行、コマンド、またはコマンド引数の一部またはすべてとして)、@variable を含めます。コンテキストに基づいて、間接演算子には 5 つのシナリオがあり、これらについて、このページで説明します。

以下は、ターミナル・セッションで示された簡単な例です。

USER>set y="B"
 
USER>set @y = 123
 
USER>write B
123

制限と代替方法

間接演算は、明らかに便利な場合にのみ使用します。間接演算は、InterSystems IRIS がコンパイル・フェーズの間ではなく、実行時に必要な評価を実行するため、性能に影響を与える可能性があります。また、複雑な間接演算を使用する場合、明確なコードを記述する必要があります。間接演算は、コード解析を複雑にする場合があるからです。

間接演算は、他の方法より能率的かつ汎用的にコーディングできますが、必ずしも使用する必要はありません。XECUTE コマンドなど他の方法を使用して、間接演算と同様の機能を常に実行できます。

間接演算は、ドット構文には使用できません。ドット構文が実行時ではなく、コンパイル時に構文解析されるためです。

Important:

オブジェクト・プロパティの値の取得または設定に間接演算子を使用しないでください。これを使用した場合、プロパティのアクセサ・メソッド (<PropertyName>Get および <PropertyName>Set) がバイパスされるため、エラーが生じることがあります。間接的にオブジェクト・プロパティの値を取得または設定する必要がある場合は、これを目的とした $CLASSMETHOD$METHOD、および $PROPERTY 関数を使用します。"オブジェクトへの動的アクセス" を参照してください。

シナリオ : 名前間接演算

名前間接演算では、間接演算は、変数名、行ラベル、ルーチン名として評価されます。InterSystems IRIS は、変数の内容をコマンド実行前に要求された名前に置換します。

名前間接演算は、パブリック変数にのみアクセスできます。詳細は、"ユーザ定義コード" を参照してください。

名前付き変数を参照するために間接演算を使用する場合、間接演算の値は、必要な添え字すべてを含め、完全なグローバル変数名またはローカル変数名にする必要があります。

行ラベルを参照するために間接演算を使用する場合、間接演算の値は、構文的に有効な行ラベルにする必要があります。以下の例では、InterSystems IRIS は D を以下のように設定します。

  • N が 1 の場合、行ラベルの値は FIG

  • N が 2 の場合、行ラベルの値は GO

  • その他の場合の値は STOP

その後、InterSystems IRIS は D に値が与えられたラベルに制御を渡します。

B SET D = $SELECT(N = 1:"FIG",N = 2:"GO",1:"STOP")
 ; ...
LV GOTO @D

ルーチン名を参照するために間接演算を使用する場合、間接演算の値は、構文的に有効なルーチン名である必要があります。以下の例では、名前間接演算を DO コマンドで使用し、適切なプロシージャ名を渡します。実行時、変数 loc の内容が、要求されている名前に置換されます。

Start
 READ !,"Enter choice (1, 2, or 3): ",num
 SET loc = "Choice"_num 
 DO @loc
 RETURN
Choice1()
 ; ...
Choice2()
 ; ...
Choice3()
 ; ...

名前間接演算は、名前の値のみを置換できます。以下の例で、2 番目の SET コマンドは、コンテキストに起因するエラー・メッセージを返します。等号の右側の式を評価する際、InterSystems IRIS は @var1 を数値ではなく、変数名に対する間接参照と解釈します。

 SET var1 = "5"
 SET x = @var1*6

正確に実行するには、上記の例を以下のように修正します。

 SET var1 = "var2",var2 = 5
 SET x = @var1*6

シナリオ : パターン間接演算

パターン間接演算では、間接演算子はパターン・マッチを置換します。間接演算の値は、有効なパターンの必要があります。("パターン・マッチング (?)" を参照してください。)パターン間接演算は、可能性のあるパターンを複数選択し、それらを単一のパターンとして使用する場合に特に役立ちます。

以下の例では、間接演算をパターン・マッチングに使用し、郵便番号 (ZIP) が有効かどうかを判断します。コードは、5 桁 (nnnnn) あるいは 9 桁 (nnnnnnnnn) のいずれかです。

最初の SET コマンドは、5 桁の形式に対するパターンを設定します。次の SET コマンドは、9 桁の形式に対するパターンを設定します。この 2 番目の SET コマンドは、後置条件式 ($LENGTH(zip) = 10) が True (0 以外) の場合に実行されます。この条件は、ユーザが 9 桁を入力した場合にのみ発生します。

GetZip()
 SET pat = "5N"
 READ !,"Enter your ZIP code (5 or 9 digits): ",zip
 SET:($LENGTH(zip)=10) pat = "5N1""-""4N"
 IF zip'?@pat { 
   WRITE !,"Invalid ZIP code"
   DO GetZip()
 }

パターン・マッチングに間接演算を使用すると、アプリケーション中で使用するパターンをローカライズするのに便利です。この場合、パターンをそれぞれ別々の変数に格納しておき、実際のパターン・テストでは間接演算でそれらを参照できます(これは、名前間接演算の例でもあります)。このようなアプリケーションを移植するには、パターン変数自体を変更するだけで済みます。

シナリオ : 引数間接演算

引数間接演算では、間接演算の結果は、1 つ以上のコマンド引数として評価されます。一方、名前間接演算は、引数の一部のみを適用します。

この違いを理解するには、以下の例と "名前間接演算" の例を比較してください。

Start
 SET rout = "^Test1"
 READ !,"Enter choice (1, 2, or 3): ",num
 SET loc = "Choice"_num_rout 
 DO @loc
 QUIT

この場合の引数間接演算の例は、@loc が引数を完全な形式 (すなわち、label^routine) で提供します。名前間接演算の例では、@loc は引数の一部分のみ提供するため、@loc が名前間接演算の例となります (エントリ・ポイントが、別のルーチンではなく、現在のルーチンに存在する label 名)。

以下の 2 番目の SET コマンドは、名前間接演算 (変数名である引数の一部のみに適用) の例であり、一方、3 番目の SET コマンドは、引数間接演算 (引数全体に適用) の例です。

 SET a = "var1",b = "var2 = 3*4"
 SET @a = 5*6
 SET @b
 WRITE "a = ",a,!
 WRITE "b = ",b,!

シナリオ : 添え字間接演算

添え字間接演算は、名前間接演算の拡張形式です。添え字間接演算では、間接演算の値はローカルあるいはグローバルの配列ノード名である必要があります。また、他の間接演算とは構文的に異なります。添え字間接演算は、以下の 2 つの間接演算子を使用します。

 @array@(subscript) 

^client というグローバル配列で、最初のレベルのノードにはクライアント名、2 番目にはクライアントの番地、3 番目にはクライアントの市区町村、都道府県、郵便番号が含まれていると想定します。この配列の最初のレコードにあるこれら 3 つのノードを出力するには、以下の形式で WRITE コマンドを使用します。

 WRITE !,^client(1),!,^client(1,1),!,^client(1,1,1)

実行すると、このコマンドは以下のように出力する場合があります。

John Jones
42 Arnold St.
Boston, MA 02745

レコードの範囲を出力するには (例えば、先頭から 10 件のレコード)、WRITE コマンドが FOR ループの中で実行されるようにコードを変更します。以下に例を示します。

 FOR i = 1:1:10 {
 WRITE !,^client(i),!,^client(i,1),!,^client(i,1,1)
 }

FOR ループを実行するたびに変数 i は 1 ずつ増加し、その変数を使用して、出力する次のレコードを選択します。

この例は、前述の例よりも一般的ですが、配列名と出力レコード数の両方を明示的に指定する点で特殊です。

以下のように添え字間接演算を使用して、このコードをさらに一般的な形に変更し、ユーザが、3 つのノード・レベルに名前、町名、および都市情報を格納している任意の配列 (グローバルまたはローカル) から、一定範囲のレコードをリストできるようにします。

Start
 READ !,"Output Name, Street, and City info.",!
 READ !,"Name of array to access: ",name
 READ !,"Global or local (G or L): ",gl
 READ !,"Start with record number: ",start
 READ !,"End with record number: ",end
 IF (gl["L")!(gl["l") {SET array = name}
 ELSEIF (gl["G")!(gl["g") {SET array = "^"_name}
 SET x = 1,y = 1
 FOR i = start:1:end {DO Output}
 RETURN
Output()
 WRITE !,@array@(i)
 WRITE !,@array@(i,x)
 WRITE !,@array@(i,x,y)
 QUIT

Output サブルーチンにある WRITE コマンドは、添え字間接演算を使用して、要求されている配列とレコード範囲を参照します。

添え字間接演算の評価で、間接演算のインスタンスが、添え字のないグローバルまたはローカルの変数を参照する場合、間接演算の値は、変数名、および括弧を含む 2 番目の間接演算子の右側にあるすべての文字になります。

ローカル変数の添え字レベルの最大数は 255 です。添え字間接演算は、多次元オブジェクト・プロパティに 254 個を超える添え字を参照できません。グローバル変数の添え字レベルの最大数は添え字に応じて異なり、レベルが 255 を超える場合もあります。これは、"グローバルについての正式な規則" で説明しています。間接演算を使用して 255 より大きな添え字レベルをローカル変数に移入しようとすると、<SYNTAX> エラーが返されます。

クラス・パラメータは、ローカル変数またはグローバル変数をベースとして使用するのと同様の方法で、添え字間接演算のベースとして使用できます。例えば、以下の構文でクラス・パラメータを使用して、添え字間接演算を実行できます。

  SET @..#myparam@(x,y) = "stringval"

シナリオ : $TEXT 引数間接演算

名前からわかるように、$TEXT 引数間接演算は、$TEXT 関数の引数のコンテキストでのみ使用可能です。この間接演算の値は、有効な $TEXT 引数とする必要があります。

$TEXT 引数間接演算を使用する主な目的は、同じ結果を返す間接演算を複数の形式で記述しなくても済むようにすることにあります。例えば、ローカル変数 LINE に "START^MENU" のエントリ参照が含まれている場合、行ラベルとルーチン名に対し名前間接演算を使用して、行テキストを取得できます。以下がその例です。

 SET LINETEXT = $TEXT(@$PIECE(LINE,"^",1)^@$PIECE(LINE,"^",2))

以下のように $TEXT 引数間接演算を使用すると、より単純な方法で同じ結果を返すことができます。

 SET LINETEXT = $TEXT(@LINE)
FeedbackOpens in a new tab