Perl の変数にはいくつかのタイプがあります。よく使用されるタイプには、次のものがあります。
グローバル変数は固有の名前で指定しなければなりません。また、my 規則を使用して、ローカル変数を使用することもできます。例を次に示します。
my ($uvComponent);
既存の Perl フックでは、名前検索の問題が発生する可能性があります。 Rational® ClearQuest® アクションでは、例えば Submit の場合、単一の Perl インタープリタですべてのアクション フック (Action Initialization など) とすべてのフィールド フック (Perl で記述された Field Value Changed など) を実行します。フック コードでローカル変数を使用する前に my キーワードでローカル変数を宣言していない場合は、変数が意図せずにフック間で共有されることがあります。
バージョン 2003.06.00 より前のリリースでは、1 つの Perl フックが別の Perl フックを呼び出した場合、2 番目のフックが別の Perl ネームスペースでコンパイルされました。 バージョン 2003.06.00 以降のリリースでは、すべてのフックが同じ Perl ネームスペースでコンパイルされます。 これは、グローバル変数が使用されている場合、別々のフック間の干渉に影響する場合があります。例を次に示します。
sub defect_Initialization { $variable = "1"; $entity->SetFieldValue("A", $variable); } sub a_ValueChanged { $entity->SetFieldValue("B", $variable); $entity->SetFieldValue("C", $variable); } sub b_ValueChanged { $variable = "3"; }
これらのフック サブルーチン内の $variable という変数は、パッケージ スコープ変数です。 これは、同じパッケージ内のサブルーチンが同じ変数を共有することを意味します。
バージョン 2003.06.00 より前のリリースでは、ネストされたフックは、最初のフックとは異なる Perl パッケージ内にあり、したがって、最初のフックとはグローバル変数を共有しませんでした。 これは、上の例が、次のようなネームスペース修飾子を持つと解釈されたということです。
package main; sub defect_Initialization { $main::variable = "1"; $entity->SetFieldValue("A", $main::variable); } package CQEntity; sub a_ValueChanged { # $CQEntity::variable is not set, so defaults to an empty string. $entity->SetFieldValue("B", $CQEntity::variable); $entity->SetFieldValue("C", $CQEntity::variable); } sub b_ValueChanged { $CQEntity::variable = "3"; }
関連フィールドの変更時にすぐに (つまり、SetFieldValue から戻る前に)、Field Value Changed フックが呼び出されるので、上のコードは次の順序で実行します。
$main::variable = "1"; # From defect_Initialization; # $main::variable is set to "1" $entity->SetFieldValue("A", $main::variable); # From defect_Initialization # Sets A to "1" # Rational ClearQuest calls a_ValueChanged before returning $entity->SetFieldValue("B", $CQEntity::variable); # From a_ValueChanged # $CQEntity::variable is uninitialized # Sets B to "" # Rational ClearQuest calls b_ValueChanged before returning $CQEntity::variable = "3"; # From b_ValueChanged # $CQEntity::variable changes from "" to "3" $entity->SetFieldValue("C", $CQEntity::variable); # From a_ValueChanged # Sets C to "3"
この結果、フィールド A、B、C は、それぞれ "1"、""、"3" に設定されます。
リリース バージョン 2003.06.00 以降では、Perl フックは、同じネームスペースにコンパイルされます。 上の例は、次のようなネームスペース修飾子を持つと解釈されるようになりました。
package main; sub defect_Initialization { $main::variable = "1"; $entity->SetFieldValue("A", $main::variable); } sub a_ValueChanged { $entity->SetFieldValue("B", $main::variable); $entity->SetFieldValue("C", $main::variable); } sub b_ValueChanged { $main::variable = "3"; }
$main::variable = "1"; # From defect_Initialization; # $main::variable is set to "1" $entity->SetFieldValue("A", $main::variable); # From defect_Initialization # Sets A to "1" # Rational ClearQuest calls a_ValueChanged before returning $entity->SetFieldValue("B", $main::variable); # From a_ValueChanged # Sets B to "1" # Rational ClearQuest calls b_ValueChanged before returning $main::variable = "3"; # From b_ValueChanged # $main::variable changes from "1" to "3" $entity->SetFieldValue("C", $main::variable); # From a_ValueChanged # Sets C to "3"
この結果、フィールド A、B、C は、それぞれ "1"、"1"、"3" に設定されます。
変数値を意図せずに共有してしまうのを避けるために、以下の形式でこれらの変数をフック関数にローカルに宣言する必要があります。
sub d_ValueChanged { my $temp = $entity->GetFieldValue("d")->GetValue(); $session->OutputDebugString("d now set to $temp¥n"); }
ここで、$temp は d_ValueChanged 関数に対してローカルに宣言され、この $temp への割り当てにより、同じ名前の別の変数の値は変更されません。 my 構文の使用により、指定されたブロックのコード内のみで変数が表示可能になります。