Búsqueda de nombre en enganches de Perl

En Perl, las variables son de varios tipos. Los tipos comunes incluyen:

Debe especificar variables globales con nombres exclusivos. También puede utilizar variables locales, mediante el convenio my. Por ejemplo:

my ($uvComponent);
Nota: Cuando establezca una variable para que sea local en un enganche de Perl, utilice la declaración my.

Es posible que los enganches de Perl existentes tengan problemas de búsqueda de nombre. Una acción de Rational ClearQuest como, por ejemplo, Enviar, utiliza un único intérprete de Perl para ejecutar todos los enganches de acción, como Inicialización de acción, y todos los enganches de campo, como Valor de campo cambiado, que se escriben en Perl. Si el código de enganche no declara variables locales con la palabra clave my antes de utilizarlas, la variable se puede compartir entre enganches de forma no intencionada.

En releases anteriores a la versión 2003.06.00, cuando un enganche de Perl llama a otro, el segundo enganche se compila en un espacio de nombres de Perl diferente. En la versión de release 2003.06.00 y posteriores, todos los enganches se compilan en el mismo espacio de nombres Perl. Esto puede afectar al modo en el que interfieren los diferentes enganches entre sí si se utilizan variables globales. Por ejemplo:

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";

} 

La variable denominada $variable en las subrutinas de este enganche es una variable de ámbito de paquete. Esto significa que las subrutinas del mismo paquete comparten la misma variable.

En los releases anteriores a la versión 2003.06.00, los enganches anidados se encontraban en un paquete Perl diferente al enganche inicial y, por lo tanto, no compartían las variables globales con el enganche inicial. Esto significa que el ejemplo anterior se interpretó como si tuviera los calificadores de espacio de nombres siguientes:

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";

} 

Al cambiar el campo asociado se llama, inmediatamente, a un enganche de valor de campo cambiado (es decir, antes de devolverlo de SetFieldValue), por lo que el código precedente se ejecuta en el orden siguiente:

 $main::variable = "1";    # De defect_Initialization;

       # $main::variable is set to "1"

 $entity->SetFieldValue("A", $main::variable); # De defect_Initialization

       # Sets A to "1"

       # Rational ClearQuest calls a_ValueChanged before returning

 $entity->SetFieldValue("B", $CQEntity::variable); # De a_ValueChanged

       # $CQEntity::variable is uninitialized

       # Sets B to ""

       # Rational ClearQuest calls b_ValueChanged before returning

 $CQEntity::variable = "3";   # De b_ValueChanged

       # $CQEntity::variable changes from "" to "3"

 $entity->SetFieldValue("C", $CQEntity::variable); # De a_ValueChanged

       # Sets C to "3" 

Como resultado, los campos A, B y C se establecen en "1", "" y "3", respectivamente.

A partir de la versión de release 2003.06.00, los enganches de Perl se compilan en el mismo espacio de nombres. El ejemplo anterior ahora se interpreta como si tuviera los calificadores de espacio de nombres siguientes:

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";

} 

Este código se ejecuta en este orden:

 $main::variable = "1";    # De defect_Initialization;

       # $main::variable is set to "1"

 $entity->SetFieldValue("A", $main::variable); # De defect_Initialization

       # Sets A to "1"

       # Rational ClearQuest calls a_ValueChanged before returning

 $entity->SetFieldValue("B", $main::variable); # De a_ValueChanged

       # Sets B to "1"

       # Rational ClearQuest calls b_ValueChanged before returning

 $main::variable = "3";    # De b_ValueChanged

       # $main::variable changes from "1" to "3"

 $entity->SetFieldValue("C", $main::variable); # De a_ValueChanged

       # Sets C to "3" 

Como resultado, los campos A, B y C se establecen en "1", "1" y "3", respectivamente.

Para evitar el compartimiento no intencionado de los valores de las variables, debe declarar que el propósito de estas variables es local en una función de enganche con el formato siguiente:

sub d_ValueChanged

{

 my $temp = $entity->GetFieldValue("d")->GetValue();

 $session->OutputDebugString("d now set to $temp\n");

} 

donde $temp se declara local para la función d_ValueChanged, y esta asignación de $temp no cambia el valor de otra variable con el mismo nombre. Utilizando la sintaxis my, la variable se hace visible sólo dentro de un bloque de código especificado.

Nota: $entity y $session son variables globales que define Rational ClearQuest Core.

Feedback