D プログラムの節ごとに再利用可能な記憶域を持つ D 変数も定義できます。節固有変数は、C、C++、Java 言語プログラムの自動変数とよく似ており、1 回の関数呼び出しが完了するまで有効です。節固有変数は、すべての D プログラム変数と同じく、最初の割り当て時に作成されます。これらの変数を参照し、割り当てるには、特殊な識別子 this に、演算子 -> を適用します。
BEGIN { this->secs = timestamp / 1000000000; ... }
節固有変数を明示的に宣言してから使用したい場合は、キーワード this を使用します。
this int x; /* an integer clause-local variable */ this char c; /* a character clause-local variable */ BEGIN { this->x = 123; this->c = 'D'; }
節固有変数は、プローブ節の終了まで有効です。DTrace により、プローブ節に関連付けられたアクションの実行が完了すると、すべての節固有変数用の記憶域が回収され、次の節で再利用されます。したがって、節固有変数は、D 変数の中で唯一、ゼロに初期化されることがありません。プログラム内の単一のプローブに複数の節が含まれている場合、これらの節の実行が完了するまで、すべての節固有変数はそのままの状態を保持します。次の例を参照してください。
int me; /* an integer global variable */ this int foo; /* an integer clause-local variable */ tick-1sec { /* * Set foo to be 10 if and only if this is the first clause executed. */ this->foo = (me % 3 == 0) ? 10 : this->foo; printf("Clause 1 is number %d; foo is %d\n", me++ % 3, this->foo++); } tick-1sec { /* * Set foo to be 20 if and only if this is the first clause executed. */ this->foo = (me % 3 == 0) ? 20 : this->foo; printf("Clause 2 is number %d; foo is %d\n", me++ % 3, this->foo++); } tick-1sec { /* * Set foo to be 30 if and only if this is the first clause executed. */ this->foo = (me % 3 == 0) ? 30 : this->foo; printf("Clause 3 is number %d; foo is %d\n", me++ % 3, this->foo++); }
節は常に記述された順に実行され、節固有変数は同じプローブを有効にする複数の節を通して変更されないので、上記のプログラムを実行したときの出力は、いつも同じになります。
# dtrace -q -s clause.d Clause 1 is number 0; foo is 10 Clause 2 is number 1; foo is 11 Clause 3 is number 2; foo is 12 Clause 1 is number 0; foo is 10 Clause 2 is number 1; foo is 11 Clause 3 is number 2; foo is 12 Clause 1 is number 0; foo is 10 Clause 2 is number 1; foo is 11 Clause 3 is number 2; foo is 12 Clause 1 is number 0; foo is 10 Clause 2 is number 1; foo is 11 Clause 3 is number 2; foo is 12 ^C |
節固有変数は、同じプローブを有効にする複数の節を通して変更されないので、あるプローブに対して実行される最初の節では、その値は未定義になります。節固有変数を使用するときは、必ず事前に適切な値を割り当ててください。そうしないと、プログラムの結果が予想どおりにならない可能性があります。
節固有変数は、任意のスカラー変数型を使って定義できますが、連想配列は、節固有のスコープでは定義できません。節固有変数のスコープは、対応する変数データだけに適用されます。この変数に定義された名前や型の識別情報には適用されません。節固有変数の定義後は、以降のすべての D プログラム節で、この名前と型署名を使用できます。記憶域は、節が変わると変更される可能性があります。
節固有変数を使って、計算の途中結果を累積できます。また、節固有変数をほかの変数の一時コピーとして使用することもできます。節固有変数には、連想配列よりも高速にアクセスできます。そのため、同じ D プログラム節内で特定の連想配列値を繰り返し参照する必要がある場合は、この値を節固有変数にコピーし、節固有変数を繰り返し参照するようにすると、効率がよくなります。