NEW (ObjectScript)
構文
NEW:pc newargument,...
N:pc newargument,...
newargument には、以下を指定できます。
variable,...
(variable,...)
引数
引数 | 説明 |
---|---|
pc | オプション — 後置条件式。 |
variable | オプション — 既存のローカル変数環境に追加される変数名。既存のローカル変数での NEW の結果は、variable が括弧に囲まれているか (排他的 NEW)、または括弧に囲まれていないか (包含的 NEW) によって異なります。variable は、有効なローカル変数名でなければなりませんが、定義済みの変数である必要はありません。未定義の変数を指定しても、エラーが出力されたり、変数が定義されたりすることはありません。 |
概要
NEW コマンドには、以下の 3 つの形式があります。
引数なしの NEW コマンドは、呼び出されるサブルーチンまたは外部関数用に、空のローカル変数環境を作成します。既存のローカル変数値は、新規のローカル環境では利用できません。この値は、以前のローカル環境に返ることによって復元されます。
引数付きの NEW コマンドのアクションは、使用する引数の形式によって異なります。
-
NEW var1,var2,...(包含的 NEW) は、既存のローカル変数環境を保持し、それに指定された変数を追加します。指定されたローカル変数のいずれかが、既存のローカル変数と同じ名前を持つ場合、その名前を持つ変数の古い値は、現在の環境ではアクセス不可能となります。
-
NEW (var1,var2,...)(排他的 NEW) は、指定された変数を除く既存のすべての変数を、ローカル変数環境で置き換えます。
引数なしの NEW
引数なしの NEW は、呼び出されるサブルーチン、または外部関数用に空のローカル変数環境を提供します。既存のローカル変数環境 (呼び出し元のルーチン内) は保存され、サブルーチンまたは関数の終了時に復元されます。NEW の後に作成された変数は、サブルーチンまたは関数の終了時にすべて削除されます。
同じ行で NEW の後にコマンドが続く場合、(最低でも) 2 つのスペースで以下のコマンドと NEW を区別する必要があります。
引数なしの NEW は、FOR ループ本文内または InterSystems IRIS オブジェクトに影響を与える可能性のあるコンテキスト内では使用できません。
31 レベルを超える排他的 NEW コマンドや引数なしの NEW コマンドの発行を試みると、<MAXSCOPE> エラーが返されます。
包含的 NEW
包含的 NEW — NEW var1,var2 は、既存のローカル変数環境を保持し、それに指定された変数を追加します。既存の変数が指定された場合、"NEW" 変数によって、既存の変数が置き換えられます。既存の変数は、スタックに保存され、サブルーチンまたは関数の終了後に復元されます。
包含的 NEW では、コンマ区切りのリストとして指定できる変数の数は制限されません。また、ローカル変数環境レベルの数 (NEW コマンドの発行回数) も制限されません。
以下の例では、呼び出し元のルーチン (Main) のローカル変数環境が、変数 a、b、c で構成されていると仮定しています。DO が Subr1 を呼び出すと、NEW コマンドが Subr1 のローカル変数環境を再定義し、c を新しい変数にして変数 d を追加します。NEW の後、サブルーチンの環境は、既存の変数 a および b に新しい変数 c および d を加えて構成されています。変数 a および b は、継承されたもので、既存の値を保持しています。新しい変数 c および d は、未定義で作成されます。c は既存のローカル変数の名前であるため、システムは既存の値をスタックに格納し、Subr1 が QUIT を実行するときに c を復元します。Subr1 の最初の SET コマンドは a および b を参照して、d に値を代入していることに注意してください。このコンテキストで、変数 c は未定義です。
Main
SET a=2,b=4,c=6
WRITE !,"c in Main before DO: ",c
DO Subr1(a,b,c)
WRITE !,"c in Main after DO: ",c
QUIT
Subr1(a,b,c)
NEW c,d
IF $DATA(c) {WRITE !,"c=",c}
ELSE {WRITE !,"c in Subr1 is undefined"}
SET d=a*b
SET c=d*2
WRITE !,"c in Subr1: ",c
QUIT
このコードが実行されると、以下の結果が生成されます。
c in Main before DO: 6 c in Subr1 is undefined c in Subr1: 16 c in Main after DO: 6
この結果は、前述の例のように値によるパラメータ渡しでも、参照によるパラメータ渡しでも同じになります。
Main
SET a=2,b=4,c=6
WRITE !,"c in Main before DO: ",c
DO Subr1(.a,.b,.c)
WRITE !,"c in Main after DO: ",c
QUIT
Subr1(&a,&b,&c)
NEW c,d
IF $DATA(c) {WRITE !,"c=",c}
ELSE {WRITE !,"c in Subr1 is undefined"}
SET d=a*b
SET c=d*2
WRITE !,"c in Subr1: ",c
QUIT
変数 c は Subr1 に渡され、NEW を使用して直ちに再定義されます。この場合、変数 c を渡す必要はありません。c が渡されるかどうかにかかわらず、このプログラムの結果は同じです。サブルーチンの仮パラメータ・リスト内の任意の変数に対して NEW を実行する場合は、これらを未定義で表示し、渡された値をアクセス不可にします。
排他的 NEW
排他的 NEW — NEW (var1,var2) — は、指定された変数を除く既存のローカル変数環境全体を置換します。既存の変数が指定された場合、それが保持され、新しい環境でも参照可能になります。ただし、そのような変数に行われた変更は、関数またはサブルーチンの終了時に、既存の変数に反映されます。
包含的 NEW では、コンマ区切りリストとして最大 255 の変数を指定できます。この数を超えると、InterSystems IRIS では <SYNTAX> エラーが出力されます。
排他的 NEW (NEW (x,y,z)) は、ローカル変数を現在の範囲から一時的に削除します。これは、InterSystems IRIS オブジェクトによって生成されたローカル変数に影響を及ぼす可能性があります。例えば InterSystems IRIS は、InterSystems IRIS のオブジェクト・クエリに対するカーソル・ポインタである %objcn を保持します。これを現在の範囲から削除すると、他の内部構造との衝突を引き起こします。したがって、システム構造に影響を与える可能性のあるコンテキストでは、排他的 NEW を使用してはなりません。
31 レベルを超える排他的 NEW コマンドや引数なしの NEW コマンドの発行を試みると、<MAXSCOPE> エラーが返されます。
FOR コード・ブロックで排他的 NEW を使用している場合、除外する変数として FOR の count 変数を指定する必要があります。詳細は、"FOR コマンド" を参照してください。
以下の例では、呼び出し元のルーチン (Start) のローカル変数環境が、変数 a、b、および c で構成されていると仮定しています。DO が Subr1 を呼び出すと、NEW コマンドが Subr1 のローカル変数環境を再定義して、変数 c および d 以外のすべての変数を除外します。
NEW の後、サブルーチンの環境は、新しい変数 c および d だけで構成されています。新しい変数 c は、呼び出し元のルーチンの環境から維持されており、その既存の値を保持しています。新しい d は、未定義で作成されます。
Subr1 の最初の SET コマンドは c を参照して、d に値を代入しています。2 番目の SET コマンドは、新しい値 (24) を c に代入しています。サブルーチンが QUIT を実行するとき、c は、呼び出し元のルーチンの環境では、この更新された値を保持します (元の値 6 ではありません)。
Start SET a=2,b=4,c=6
DO Subr1
WRITE !,"c in Start: ",c
QUIT
Subr1 NEW (c,d)
SET d=c+c
SET c=d*2
WRITE !,"c in Subr1: ",c
QUIT
このコードが実行されると、以下の結果が生成されます。
c in Subr1:
c in Start:
引数
pc
オプションの後置条件式。InterSystems IRIS は、後置条件式が True (0 以外の数値に評価される) の場合に NEW コマンドを実行します。InterSystems IRIS は、後置条件式が False (0 に評価される) の場合はコマンドを実行しません。詳細は、"コマンド後置条件式" を参照してください。
variable
variable は単一の変数、またはコンマで区切られた変数名のリストです。指定できるのは添え字なしの変数名だけですが、配列全体 (つまり添え字なしの配列名) に NEW を実行できます。未定義の変数名を指定したり、既存のローカル変数の名前を再使用することができます。包含的 NEW では、既存のローカル変数を指定する場合、InterSystems IRIS はローカル環境のその変数を再初期化しますが、プログラム・スタックで現在の値を保存し、サブルーチンまたは関数の終了後に復元します。
変数名、または変数名のコンマ区切りのリストが括弧で囲まれているとき (排他的 NEW)、InterSystems IRIS は反対のオペレーションを実行します。つまり、すべてのローカル変数は、指定された変数名を除いて再度初期化され、指定された変数は、以前の値を保持します。InterSystems IRIS はプログラム・スタックのすべての変数で現在の値を保存し、サブルーチンまたは関数の終了後に値を復元します。
NEW コマンド (包括的または排他的) は、以下で使用することはできません。
NEW を上記のコンテキストで使用すると、<SYNTAX> エラーが返されます。
NEW を使用する場所
NEW を使用すると、現在のプロセスのローカル変数環境をサブルーチン、ユーザ定義関数、または XECUTE された文字列による変更から保護することができます。NEW は、DO コマンドによって呼び出されたサブルーチン内で、最も頻繁に使用されます。
NEW コマンドの基本的な用途は、呼び出されるサブルーチン、または外部関数内のローカル変数環境の再定義です。パラメータ渡しなしで呼び出されたサブルーチン、または外部関数は、呼び出し元のルーチンのローカル変数環境を継承します。サブルーチン、または関数に対するこの環境を再定義するには、すべてのローカル変数 (引数なしの NEW)、指定されたローカル変数 (包含的 NEW)、または指定された変数を除くすべてのローカル変数 (排他的 NEW) に対して NEW を使用することができます。
プロシージャ内では、変数はプライベートまたはパブリックです。
-
既定では、ローカル変数はそのプロシージャに対してプライベートです。そのプロシージャ・ブロックでは、その外部に存在する同名の変数とは対話しないプライベート変数を使用します。プライベート変数に対して NEW を実行することはできません。プロシージャ・ブロック内のプライベート変数に対して包含的または排他的 NEW を実行しようとすると、<SYNTAX> エラーが発生します。
-
プロシージャを宣言するときに、ローカル変数をパブリック変数として明示的にリストできます。プロシージャ・ブロック内のパブリック変数に対して NEW を実行できます。この NEW は、そのプロシージャ内の変数値にのみ影響します。プロシージャ内のパブリック変数に対して NEW を繰り返し実行できます。
詳細は "プロシージャ変数" を参照してください。
パラメータ渡しの DO コマンドによって呼び出されたサブルーチンの場合は、特に配慮すべき問題があります。詳細は、"パラメータ渡しのサブルーチン" を参照してください。
NEW と KILL
NEW によって作成された変数には、対応する明示的な KILL コマンドは必要ありません。呼び出されたサブルーチンやユーザ定義関数が終了すると、InterSystems IRIS は、サブルーチンや関数内で NEW コマンドで初期化された各変数に対して、暗黙の KILL を実行します。
例
以下は、包含的 NEW の例です。これは、既存のローカル変数 a、b、および c を保持し、変数 d および e を追加し、d の以前の値を置換します。
Main
SET a=7,b=8,c=9,d=10
WRITE !,"Before NEW:",!,"a=",a,!,"b=",b,!,"c=",c,!,"d=",d
DO Sub1
WRITE !,"Returned to prior context:"
WRITE !,"a=",a,!,"b=",b,!,"c=",c,!,"d=",d
QUIT
Sub1
NEW d,e
SET d="big number"
WRITE !,"After NEW:",!,"a=",a,!,"b=",b,!,"c=",c,!,"d=",d
QUIT
以下のターミナルの例は、排他的 NEW を示しています。これは、指定された変数 a および c を除いた既存のすべてのローカル変数を削除します。
USER>SET a=7,b=8,c=9,d=10
USER>WRITE
a=7
b=8
c=9
d=10
USER>NEW (a,c)
USER 1S1>WRITE
a=7
c=9
USER 1S1>QUIT
USER>WRITE
a=7
b=8
c=9
d=10
USER>
特殊変数 : $ESTACK、$ETRAP、$NAMESPACE、および $ROLES
大半の特殊変数では NEW を使用できません。NEW を使用すると<SYNTAX> エラーが返されます。しかし、$ESTACK、$ETRAP、$NAMESPACE、および $ROLES の 4 つは例外です。
$ETRAP : NEW $ETRAP コマンドを実行すると、エラー・トラップ用の新しいコンテキストがシステムで作成されます。その後、この新しいコンテキスト内で好みのエラー・トラップ・コマンドを使用して $ETRAP を設定できます。前のコンテキストの $ETRAP 値は保持されます。最初に NEW $ETRAP コマンドを発行せずに $ETRAP を設定すると、InterSystems IRIS はすべてのコンテキストで $ETRAP をこの値に設定します。このため、常に、設定する前に $ETRAP 特殊変数に NEW を実行することをお勧めします。
$NAMESPACE : NEW $NAMESPACE コマンドを実行すると、新規ネームスペース・コンテキストがシステムで作成されます。このコンテキストでネームスペースを変更できます。例えば、QUIT を使用して現在のコンテキストを終了すると、InterSystems IRIS は直前のネームスペースに戻ります。
パラメータ渡しのサブルーチン
パラメータ渡しのサブルーチンが呼び出される場合、InterSystems IRIS は、サブルーチンの仮パラメータ・リストに指定されているすべての変数に対して、暗黙の NEW コマンドを実行します。次に、それらの変数に、DO コマンドの実パラメータリストで (値または参照によって) 渡された値を代入します。
DO コマンドが値によるパラメータ渡しを使用している場合や、仮リストが既存のローカル変数を指定している場合、InterSystems IRIS は既存の変数とその値をスタックに格納します。サブルーチンが (明示的または暗黙の QUIT で) 終了するときに、InterSystems IRIS は、仮リスト変数それぞれに対して暗黙の KILL コマンドを実行して、スタックから元の値を復元します。
関連項目
-
DO コマンド
-
KILL コマンド
-
QUIT コマンド
-
SET コマンド
-
$NAMESPACE 特殊変数