変数
変数は、値が格納される場所の名前です。ObjectScript では、変数にデータ型がなく、宣言の必要はありません。
一般的には、SET コマンドを使用して、変数に値を代入することによって変数を定義します。null 文字列 ("") の値も変数に割り当てられます。コマンドおよび関数の多くは、変数を定義してから、その変数を参照する必要があります。変数が未定義である場合、既定においては、変数を参照すると <UNDEFINED> エラーが生成されます。%SYSTEM.Process.Undefined()Opens in a new tab メソッドを設定することで、未定義の変数を参照する際に <UNDEFINED> エラーを生成しないように InterSystems IRIS® Data Platform の動作を変更できます。
READ コマンド、$INCREMENT 関数、$BIT 関数、引数を 2 つ使用した形式の $GET 関数など、演算によっては、未定義の変数を使用できます。これらの関数は値を変数に代入します。$DATA 関数の場合、未定義または定義済みの変数を使用して、その状態を返します。
多くのコンピュータ言語とは異なり、ObjectScript では変数を宣言する必要はありません。変数は、値が割り当てられたときに作成されます。ObjectScript は "タイプのない" 言語です。変数はあらゆるタイプのデータを受け取ることができます。"#dim (オプション)" および "変数のタイプと変換" を参照してください。
変数のカテゴリ
ObjectScript には、いくつかの変数の種類があります。
-
グローバル変数 (グローバル)
-
プロセス・プライベート・グローバル変数 (PPG)
-
i%property インスタンス変数 (別のページで説明)
-
特殊変数 (システム変数)
ローカル変数
ローカル変数は、現在の InterSystems IRIS プロセス内のメモリで利用可能な変数です。作成したプロセスだけにアクセス可能となります。すべてのネームスペースからアクセスできます。つまり、プロセスがネームスペースを変更しても、変数は引き続き利用可能です。プロセスの終了時、そのプロセスのローカル変数はすべて削除されます。
名前付け規約
"識別子のルールとガイドライン" では詳細を説明していますが、簡潔に説明すると、以下のようになります。
-
ローカル変数名の最初の文字は、必ず、文字、もしくはパーセント記号 (%) のいずれかです。
% 記号で始まる変数名は、"パーセント変数" と呼ばれ、その有効範囲の規則は異なります。コードでは、ローカル・パーセント変数の名前は、%Z または %z で初めます。他の名前はシステムで使用するために予約されています。
-
ローカル変数名を含め、すべての変数名では、大文字と小文字が区別されます。例えば、MYVAR、MyVar および myvar は、3 つの異なるローカル変数となります。
-
ローカル変数名は、現在のプロセスに一意であることが必要です。その他のプロセスは、同じ名前のローカル変数を持つことができます。
-
プロセス・プライベート・グローバルまたはグローバルは、ローカル変数と同じ (見かけ上の) 名前を持つことができます。例えば、myvar、^||myvar、^myvar は、3 つの異なる変数となります。
-
ローカル変数には、添え字を使用できます。"添え字に関する規則" を参照してください。
規則に準拠しないローカル変数名の場合、<SYNTAX> エラーが生成されます。ただし例外が 1 つあり、先頭がアンダースコア文字でその後に文字が続く変数名を作成しようとすると、<_CALLBACK SYNTAX> エラーが生成されます。例えば、SET x=_a です。
ローカル変数の範囲
ObjectScript コードでは、ローカル変数はすべてパブリックです。このため、現在のコンテキスト内で ObjectScript コードのプロセスによって実行されるいずれの処理からもローカル変数にアクセスできます。ローカル変数値へのアクセスには、以下のような制約があります。
-
NEW コマンドは、新しいローカル変数コンテキストを作成します。引数なしの NEW は、既存のローカル変数に何も定義されていない新しいコンテキストを作成します。NEW var は、ローカル変数 var が定義されていない新しいコンテキストを作成します。QUIT コマンドは、前のローカル変数コンテキストに戻します。
-
プロシージャ・ブロック内では、ローカル変数は既定でプライベートです。プライベート・ローカル変数は、そのプロシージャ・ブロック内でのみ定義されます。
プロシージャ・ブロック内のローカル変数は以下のように動作します。
-
プライベート変数。プロシージャ・ブロック内で使用されるローカル変数は、プライベート変数です。パブリック変数として宣言されるか % 変数でない限り、そのプロシージャ・ブロック内でのみ定義されます。既定では、スタジオで生成されるすべてのオブジェクト・メソッドがプロシージャ・ブロックを使用するため (プロシージャ・ブロック・クラス・キーワードは、クラス定義内で設定されます)、メソッドで生成されるすべての変数がプライベート変数です。プロシージャ・ブロック内のプライベート変数に NEW コマンドを使用することはできません。
-
パブリック変数。プロシージャ・ブロックでは、ローカル変数のリストをパブリック変数として明示的に宣言できます。パブリック変数として宣言された変数の値にはプロシージャ・ブロックの外部からアクセスできます。パブリック変数のこのコンマ区切りリストには、存在しない変数や % 変数を含めることができます。プロシージャ・ブロック内のパブリック変数には NEW コマンドを使用できます。
2 つのローカル変数 var1 と var2 のパブリック変数リストは、MyProc(x,y) [var1,var2] PUBLIC { code body } のように指定します (PUBLIC キーワードはプロシージャがパブリックであることを指定するもので、パブリック変数リストとは関係ないことに注意してください)。パブリック変数は、コンマ区切りのリストで指定します。添え字なしのローカル変数のみを指定できます。パブリック変数リストに添え字なしの変数を指定すると、その添え字レベルもすべてパブリックになります。単純なオブジェクト参照 (OREF) のみを指定できます。パブリック変数リストに OREF を指定すると、そのオブジェクト・プロパティもすべてパブリックになります。パブリック変数リストには、未定義の変数を含めることができます。
-
% 変数。名前が “%” で始まるローカル変数は、自動的にパブリック変数として宣言されます。これにより、プロセス内のすべてのコードから参照できる変数を、パブリックとして明示的にリストすることなく定義できます。“%Z” または “%z” で始まる変数のみをアプリケーション・コードで使用できます。その他すべての % 変数は、規則に従ってシステムで使用するために予約されています。この規則の詳細は、"識別子のルールとガイドライン" を参照してください。プロシージャ・ブロック内の % 変数には NEW コマンドを使用できます。
これらのメカニズムの詳細は、"プロシージャ変数" を参照してください。
-
-
XECUTE コマンドは、既定でローカル変数をパブリックとして定義します。XECUTE コマンド内で、明示的にローカル変数をプライベートとして定義できます。ローカル変数をプライベートまたはパブリックのいずれかとして明示的に定義する方法の詳細は、"XECUTE" を参照してください。
引数の指定なしで WRITE または ZWRITE コマンドを使用すると、現在定義されているローカル変数をすべてリストできます。また、KILL コマンドを使用して、ローカル変数を削除できます。
グローバル
グローバルは、InterSystems IRIS データベースに自動的に格納される特殊な変数です。これは固有のネームスペースにマッピングされるので、拡張参照を使用しない限り、そのネームスペース内でのみアクセスできます。グローバルは任意のプロセスからアクセスできます。グローバルは、そのグローバルを作成したプロセスの終了後も存続します。グローバルは、明示的に削除されるまで存続します。
ObjectScript コードでは、他の変数と同様にグローバルを使用できます。構文的には、グローバル名は先頭のキャレット (^) 文字により識別されます。
SET mylocal = "This is a local variable"
SET ^myglobal = "This is a global stored in the current namespace"
名前の詳細は、"識別子のルールとガイドライン" を参照してください。概要は以下のようになります。
-
キャレットの後の最初の文字は必ず、文字、もしくはパーセント記号 (%) のいずれかです。
^% で始まるグローバル名は、"パーセント変数" と呼ばれ、すべてのネームスペースで使用できます。コードでは、これらの変数の名前は、^%Z または ^%z で始めます。他の名前はシステムで使用するために予約されています。
-
グローバル名の 2 番目およびその後に続く文字は、文字、数字、ピリオド記号 (.) になります。ピリオドを、名前の最初または最後の文字にすることはできません。
-
ローカル変数とは異なり、グローバル名には、Unicode 文字 (ASCII 255 よりもコード値が大きい文字) を使用できません。グローバル名に Unicode 文字を使用すると <WIDE CHAR> エラーが発生します。
-
グローバル名は、大文字と小文字を区別します。
-
グローバル名は、そのネームスペース内で重複しないようにします。
-
グローバル名は、接頭語を除き最大 31 文字です。31 文字より長い名前を指定することもできますが、最初の 31 文字のみが使用されます。このため、グローバル名は最初の 31 文字内で一意である必要があります。
-
インターシステムズで使用する目的で保持されているグローバル名もあります。"回避する必要があるグローバル変数名" を参照してください。
別のネームスペースにあるグローバルを参照するには、拡張参照を使用できます。この構文には、キャレット文字のすぐ後に垂直バーまたは角括弧のペアを使用します (^|"samples"|myglobal または ^|""|myglobal など)。これらの構文をプロセス・プライベート・グローバルと混同しないでください。
グローバルの詳細は、"グローバルの使用法" を参照してください。
プロセス・プライベート・グローバル
プロセス・プライベート・グローバルは、これを作成したプロセスによってのみアクセス可能な変数です。プロセスの終了時、プロセス・プライベート・グローバルはすべて削除されます。
-
プロセス固有 : プロセス・プライベート・グローバルは、作成元のプロセスからのみアクセス可能で、そのプロセスが完了すると存在しなくなります。これは、ローカル変数と同様です。
-
常にパブリック : プロセス・プライベート・グローバルは常にパブリック変数です。これは、グローバル変数と同様です。
-
ネームスペース非依存 : プロセス・プライベート・グローバルは、すべてのネームスペースからアクセスできます。
-
引数なしの KILL、NEW、WRITE、または ZWRITE の影響を受けない : プロセス・プライベート・グローバルを KILL、WRITE、または ZWRITE の引数として指定できます。これは、グローバル変数と同様です。
プロセス・プライベート・グローバルは、サイズの大きなデータ値に使用することができます。多くの場合、Mgr/Temp ディレクトリで使用するための置換値の役割を果たし、プロセスの終了時に自動クリーンアップを行います。
名前付け規約
プロセス・プライベート・グローバル名は、次のいずれかの形式となります。
^||name
^|"^"|name
^["^"]name
^["^",""]name
これらの 4 つの接頭語は同等で、4 つはいずれも同じプロセス・プライベート・グローバルを参照します。最初の形式 (^||name) がもっとも一般的で、新しいコードに推奨されるものです。2 番目 ~ 4 番目の形式は、グローバルを定義する既存のコードとの互換性のために提供されています。
接頭語を除き、プロセス・プライベート・グローバルは、"識別子のルールとガイドライン" で説明するように、通常のグローバルと同じ名前付け規約を使用します。概要は以下のようになります。
-
最初の文字 (2 番目の垂直バーの後) は、文字、もしくはパーセント記号 (%) のいずれかにする必要があります。
% で始まるプロセス・プライベート変数名は、"パーセント変数" と呼ばれ、その有効範囲の規則は異なります。コードでは、これらの変数の名前は、%Z または %z で始めます。他の名前はシステムで使用するために予約されています。例えば、^||%zmyvar のようになります。
-
ローカル変数とは異なり、グローバル名 (プロセス・プライベート・グローバルを含む) には、Unicode 文字 (ASCII 255 よりもコード値が大きい文字) を使用できません。プロセス・プライベート・グローバル名に Unicode 文字を使用すると <WIDE CHAR> エラーが発生します。
-
このプロセス・プライベート・グローバル名を含め、すべての変数名では、大文字と小文字が区別されます。
-
プロセス・プライベート・グローバル名は、プロセス内で一意である必要があります。
-
ローカル変数とは異なり、プロセス・プライベート・グローバル名は、接頭語を除き最大 31 文字です。31 文字より長い名前を指定することもできますが、最初の 31 文字のみが使用されます。このため、プロセス・プライベート・グローバル名は最初の 31 文字内で一意である必要があります。
-
その他の変数と同様に、プロセス・プライベート・グローバルには添え字を使用できます。"添え字に関する規則" を参照してください。
プロセス・プライベート・グローバルのリスト
^$GLOBAL() の ^$||GLOBAL() 構文形式を使用して、現在のプロセスに属するプロセス・プライベート・グローバルに関する情報を返すことができます。
^GETPPGINFO ルーチンを使用して、現在のすべてのプロセス・プライベート・グローバルの名前およびそれらのスペース割り当てをブロック単位で表示できます。^GETPPGINFO はプロセス・プライベート・グローバルの添え字も値もリストしません。プロセス ID (pid) を指定することで、特定プロセスのプロセス・プライベート・グローバルを表示できます。また、ワイルドカード文字列 (*) を指定することで、すべてのプロセスのプロセス・プライベート・グローバルを表示できます。^GETPPGINFO を呼び出すには %SYS ネームスペースで作業する必要があります。
以下の例では、^GETPPGINFO を使用して、現在のすべてのプロセスのプロセス・プライベート・グローバルをリストします。
SET ^||flintstones(1)="Fred"
SET ^||flintstones(2)="Wilma"
NEW $NAMESPACE
SET $NAMESPACE="%SYS"
DO ^GETPPGINFO("*")
^GETPPGINFO ルーチンは、以下のように引数を取ります。
do ^GETPPGINFO("pdf","options","outfile")
これらの引数は以下のとおりです。
-
pdf はプロセス ID または * ワイルドカードにすることができます。
-
options は次の文字列のあらゆる組み合わせにすることができます。
-
b (バイト数で値を返す)
-
Mnn (nn 個以上のブロックを使用するプロセス・プライベート・グローバルがあるプロセスのみをリストする)
プロセス・プライベート・グローバルがないプロセスをリストに含めるには M0 を使用します。
プロセス・プライベート・グローバルがないプロセスはリストから除外し、グローバル・ディレクトリ・ブロックのみがあるプロセスを含めるには M1 を使用します (これが既定です)。
プロセス・プライベート・グローバルがないプロセスをリストから除外し、グローバル・ディレクトリ・ブロックのみがあるプロセスも除外するには M2 を使用します。
-
S (outfile と共に使用して画面表示を抑制)
-
T (プロセスの合計数のみを表示)
-
-
outfile は、^GETPPGINFO 出力を受け取る CSV (コンマ区切り値) 形式ファイルのファイル・パスです。
次の例では、プロセス・プライベート・グローバルを ppgout という名前の出力ファイルに書き込みます。S オプションで画面表示を抑制し、出力を 500 ブロック以上使用するプロセス・プライベート・グローバルがあるプロセスのみを M500 オプションで表示します。
NEW $NAMESPACE
SET $NAMESPACE="%SYS"
DO ^GETPPGINFO("*","SM500","/home/myspace/ppgout")
添え字に関する規則
ローカル変数、プロセス・プライベート変数、およびグローバル変数はすべて、添え字を使用できます。いずれの場合も、以下の点に注意してください。
-
添え字は数値または文字列にすることができます。添え字には Unicode 文字をはじめ、あらゆる文字を含めることができます。有効な数値の添え字は、正と負の数、ゼロ、および小数を含みます。
-
空の文字列 ("") は有効な添え字ではありません。
-
添え字の値は、大文字と小文字で区別されます。
-
数値の添え字はキャノニック形式に変換されます。そのため、例えば、グローバル・ノード ^a(7)、^a(007)、^a(7.000)、および ^a(7.) はすべて同じです。これらすべてにおいて添え字は実際には同一であるためです。
-
文字列の添え字はキャノニック形式に変換されません。そのため、例えば ^a("7")、^a("007")、^a("7.000")、および ^a("7.") では、添え字はすべて異なるため、これらはすべて異なるグローバル・ノードになります。また、^a("7") および ^a(7) はどちらも同じグローバル・ノードを参照します。これらの添え字は同じであるためです。
-
添え字の長さと、添え字レベルの数には制限があります。"添え字の制限" を参照してください。
また、"一般的なシステム制限"も参照してください。
ロック名の添え字は変数の添え字と同一の規約に従います。
$QSUBSCRIPT 関数を使って、指定した変数のコンポーネント (名前と添え字) を返したり、$QLENGTH 関数を使って、添え字レベルの数を返すことができます。
変数のタイプと変換
ObjectScript の変数には決まった形式はありません。つまり、特定のデータ型はありません (これは、JavaScript、VBScript、および Document Data Base/JSON にも当てはまります)。したがって、文字列値を変数に割り当て、その後同じ変数に数値を割り当てることができます。最適化として、InterSystems IRIS は文字列、整数、数字、オブジェクトに異なる内部表現を使用しますが、アプリケーション・プログラマからは見えません。InterSystems IRIS は、使用されるコンテキストを基にして、変数の値を自動的に変換 (または解釈) します。
以下はその例です。
// set some variables
SET a = "This is a string"
SET b = "3 little pigs"
SET int = 22
SET num = 2.2
SET obj = ##class(Sample.Person).%New()
// Display them
WRITE "Here are the variables themselves: ",!
WRITE "a: ",a,!
WRITE "b: ",b,!
WRITE "int: ",int,!
WRITE "num: ",num,!
WRITE "obj: ",obj,!,!
// Now use them as other "types"
WRITE "Here are the numeric interpretation of",!
WRITE "a, b, and obj: ",!
WRITE "+a: ",+a,!
WRITE "+b: ",+b,!
WRITE "+obj: ",+obj,!,!
WRITE "Here are concatenations of int and num:",!
WRITE "Concatenating int: ","I found " _ int _ " apples.",!
WRITE "Concatenating num: ","There are " _ num _ " pounds per kilogram.",!
InterSystems IRIS は、以下のように値を変換します。
変換元 | 変換先 | 規則 |
---|---|---|
番号 | 文字列 | 数値を表す文字列が使用され、前の例では変数 num は 2.2 のようになります。 |
文字列 | 数値 | 文字列の先頭文字は数値リテラルとして解釈されます。これについては、"文字列から数値への変換" で説明しています。例えば、“–1.20abc” は -1.2 と解釈され、“abc123” は 0 と解釈されます。 |
オブジェクト | 数値 | 指定されたオブジェクト参照の内部オブジェクト・インスタンス番号が使用されます。その値は整数です。 |
オブジェクト | 文字列 | n@cls 形式の文字列が使用されます。n は内部オブジェクトのインスタンス番号で、cls は指定されたオブジェクトのクラス名です。 |
数値 | オブジェクト | 許可されていません。 |
文字列 | オブジェクト | 許可されていません。 |
#dim (オプション)
他の言語と異なり、ObjectScript で変数を宣言する必要はありません。ただし、#dim プリプロセッサ指示文をコードの記述の補助として使用できます。IDE ではこれを利用してコード入力サポートを提供します。
#dim の構文形式は、以下のとおりです。
#dim VariableName As DataTypeName
#dim VariableName As List Of DataTypeName
#dim VariableName As Array Of DataTypeName
ここで、VariableName は、データ型を指定する変数で、DataTypeName は、そのデータ型を指定します。
グローバル変数とジャーナリング
InterSystems IRIS では、グローバルの SET と KILL は、ジャーナル化されたトランザクション・イベントとして扱われます。このようなイベントでは、トランザクションをロールバックすると、これらの処理が取り消されて元の状態に戻ります。他のプロセスからアクセスできないように、変更したトランザクションがコミットされるまでロックを使用できます。詳細は、"トランザクション処理" を参照してください。
対照的に、ローカル変数またはプロセス・プライベート・グローバル変数の SET または KILL は、ジャーナル化されたトランザクション・イベントとして扱われません。このようなイベントでは、トランザクションをロールバックしても、これらの処理には何の影響もありません。
特殊変数
ObjectScript には、特定のシステム情報をアプリケーションで有効にするために使用する特殊変数 (システム変数ともいいます) があります。特殊変数はすべて InterSystems IRIS で供給される変数で、$ 記号の接頭辞を使用した名前を使用します。ユーザがその他の特殊変数を定義することはできません。特殊変数はすべてのネームスペースで使用できます。
その値は、ユーザの現在の動作環境に合わせて設定されます。特殊変数の一部は、はじめ NULL 文字列 ("") に設定されているため、特殊変数を参照しても <UNDEFINED> エラーは生成されません。特殊変数の値は現在のプロセスに固有のもので、別のプロセスからアクセスできません。
ユーザは、SET コマンドを使用して一部の特殊変数を設定できますが、それ以外の特殊変数をユーザが変更することはできません。詳細は、個々の特殊変数を参照してください。
次の例では、特殊変数 $HOROLOG を使用します。
SET starttime = $HOROLOG
HANG 5
WRITE !,$ZDATETIME(starttime)
WRITE !,$ZDATETIME($HOROLOG)
特殊変数 $HOROLOG は、現在のシステムの日付と日時を格納します。SET コマンドはこの特殊変数を使用して、ユーザ定義のローカル変数 starttime にこの値を設定します。HANG コマンドは、プログラムを 5 秒間停止します。最後に、2 つの $ZDATETIME 関数は、starttime と現在のシステムの日付と時間をユーザが読み取れる形式で返します。
以下はその他の特殊変数の例です。
WRITE !,"$JOB = ",$JOB // Current process ID
WRITE !,"$ZVERSION = ",$ZVERSION // Version info
多くの特殊変数は読み取り専用で、SET コマンドを使用して設定することができません。$DEVICE などのその他の特殊変数は、読み取り/書き込み可能で、SET コマンドで設定できます。
特殊変数には、添え字を使用できません。特殊変数は、$INCREMENT 関数を使用してインクリメントすることや KILL コマンドを使用して削除することができません。特殊変数は、"表示 (書き込み) コマンド" で説明するように、WRITE、ZWRITE、ZZWRITE、または ZZDUMP コマンドを使用して表示できます。
特殊変数のリストと詳細説明は、"ObjectScript リファレンス" を参照してください。