9 de septiembre de 2005

Alcance en Visual FoxPro - Parte 1

Artículo original: Scoping in Visual FoxPro - Part 1
http://weblogs.foxite.com/andykramek/archive/2005/05/04/421.aspx
Autor: Andy Kramek
Traducido por: Ana María Bisbé York

Lamento la demora que ha habido en esta publicación. Las cosas han estado un poco agitadas en los últimos 10 días. En cualquier caso, he aquí la siguiente serie. Esta vez voy a referirme al alcance de las variables y la semana que viene voy a continuar con las Propiedades y métodos. Espero que lo disfruten.

Alcance en Visual FoxPro - Parte 1

Uno de los aspectos que causa confusión es el alcance de propiedades, métodos y variables en Visual FoxPro. De hecho, es realmente muy sencillo; pero puede ser confuso debido a las diferencias en la sintaxis y su significado. Comencemos, esta semana, con las variables y veremos las propiedades y métodos la semana que viene.

Alcance de las variables

El alcance de las variables define cuánto tiempo existirán y qué programas, métodos, procedimientos o Funciones Definidas por el usuario (UDFs) tienen acceso a ellas. Para ver el tema del alcance veremos el término "procedimiento" que incluye programas, métodos, procedimientos y UDFs. Teniendo esto en mente, existen tres niveles de alcance.

Variables públicas (Public)

Se conocen también como Globales - de hecho se recomienda emplear g como identificador de alcance para variables públicas (la letra "p" se reserva para variables privadas "private"). Una variable pública está disponible en una aplicación entera independientemente de dónde o cuándo es creada. Existe, hasta que sea liberada con RELEASE o que la aplicación (o el VFP) se cierren. Esto significa que cualquier programa puede leer, o cambiar el valor de la variable en cualquier momento. Mientras existen situaciones muy específicas en las que la variable pública es la única solución, como regla general su uso en código de programas no es recomendado - son demasiado vulnerables a cambios inesperados, como para ser confiables.

Habiendo dicho esto, es importante comprender que todas las variables creadas en la ventana de comandos tienen alcance público - y esto es lo que produce el grito de "trabaja en la ventana de comandos; pero no en el EXE". Aunque hay una excepción. En todas las otras circunstancias una variable pública debe ser declarada explícitamente antes que le sea asignado un valor y si no lo hacemos ocurre un error. Por esta razón vemos frecuentemente PUBLIC precedido por un comando RELEASE (vea el código abajo). Al ejecutar un comando PUBLIC se crea(n) la(s) variable(s) y se inicializa(n) en falso .F.
*** Declara un par de variables públicas
RELEASE gnPubNum, gcPubStr
PUBLIC gnPubNum, gcPubStr
*** Hasta que le sea asignado un valor específico
*** las variables públicas tienen valor .F.
gnPubNum = 100
gcPubStr = "cadena de ejemplo"

Variables privadas (Private)

Una variable privada está disponible para el procedimiento que la creó y para cualquier procedimiento que sea llamado por el que la crea, o llamado en la cadena de procedimientos inicializada por el que la crea. Cuando finaliza este procedimiento, la variable se libera automáticamente. Si no ha sido especificado otro alcance, cuando se asigna un valor a una variable, Visual FoxPro la implementa como variable privada. Esto significa que todo lo que hace falta para crear una variable privada es, asignarle valor:
*** Crea las siguientes variables como privadas
pnPriNum = 100
pcPriStr = "Cadena Private"
Aunque,  hay que tener cuidado en una cosa. Si el nombre de la variable ya existe con un alcance determinado (por ejemplo ha sido declarada como Public o Private en un procedimiento padre, las asignaciones mostradas antes no van a crear variables nuevas, sencillamente van a cambiar el valor de la variable existente con ese nombre. No es siempre lo que buscamos y puede ser muy difícil encontrar el lugar que ocasiona un problema. Considere el código siguiente:
*** Ejecuta el procedimiento hijo 3 veces
FOR lnCnt = 1 TO 3
  CallChild(lnCnt * 4
)NEXT
*** Definición del procedimiento hijo
CallChild(tnCounter)
FOR lnCnt = 1 TO tncounter
  ? "Número del lazo: " + TRANSFORM(lnCnt)
NEXT
Pregúntese ahora, ¿cuántas veces se ejecutará el procedimiento hijo? La respuesta es, por supuesto, una vez ! El mismo nombre de contador de ciclo (lnCnt) se emplea en ambos procedimientos (padre e hijo), con el resultado que después de la primera llamada al procedimiento hijo el valor será 4 (es decir lnCnt = 1* 4) y se rompe el ciclo del programa padre. Este es un ejemplo bien obvio de cuán mal pueden ir las cosas con las variables privadas - suponga que en lugar de un par de líneas, el segundo empleo de lnCnt es un archivo de programa diferente ejecutado tres o cuatro niveles más abajo en la cadena de llamadas. Depurar lo que está mal puede ser un gran dolor de cabeza.

Afortunadamente, el uso del comando PRIVATE controla este tema por nosotros. Sin embargo, a diferencia del comando PUBLIC no crea automáticamente una variable nueva. En su lugar, dice a Visual FoxPro que cuando (y si) un nuevo valor es asignado a un nombre de variable específico, debe ignorar cualquier variable existente y crear una nueva, de la que es propietaria el procedimiento actual. Si se re-utiliza un nombre de variable existente (como hice en el ejemplo anterior); pero declarando PRIVATE antes de asignar un valor y luego mirar en el depurador, verá que VFP conserva la variable original; pero ahora está oculta "hidden" y se ha creado una nueva.
Nota: La sentencia PARAMETERS es equivalente a PRIVATE. Las variables definidas empleando este comando son creadas como si hubieran sido declaradas explícitamente como privadas con el mismo nombre que tienen alcance oculto hidden.
Variables locales (Local)


Las variables locales, al igual que las privadas tienen alcance en el procedimiento que las ha creado y luego se liberan tan pronto como acabe ese procedimiento. Sin embargo, a diferencia de las privadas, no tienen visibilidad fuera de su procedimiento padre y deben ser declaradas explícitamente utilizando el comando LOCAL. Cuando se ejecuta el comando LOCAL se crea inmediatamente una nueva variable y se inicializa en .F. (esto se contrasta con el comando PRIVATE que en realidad no crea la variable).

La única vía para que pueda ser modificada una variable local fuera de su procedimiento es que se pase como parámetro por referencia. Es decir:
*** Crea una variable local
LOCAL lnVar
? lnVar && .F.
lnVar = 100
? lnVar && 100
*** Llama a una función y pasa el parámetro por valor
func1(lnVar)
? lnVar && Still 100
*** Llama a una función y pasa el parámetro por referencia
func1(@lnVar)
? lnVar && Ahora ha cambiado!!!

FUNCTION func1(tnValue)
  tnValue = 250
  RETURN
ENDFUNC

Escritura y nombres débilmente tipados

Las variables de Visual FoxPro tienen escritura débilmente tipada "weakly typed". Esto significa que aunque a una variable se le puede asignar un valor específico, no está restringido para guardar solamente valores de un tipo en específico. En pocas palabras, las variables en Visual FoxPro tienen apariencia de camaleón con su capacidad de adaptarse al color del fondo. El siguiente código es perfectamente legítimo en Visual FoxPro aunque en realidad no estaría permitido en cualquier lenguaje estrictamente tipado. (El resultado de ejecutar esta serie de comandos será una matriz de 6 elementos llamada "lunknown" con la fecha de hoy en cada uno de sus elementos.)
lunknown = "Andy and Marcia"
lunknown = 10
DIMENSION lunknown[3,2]
lunknown = DATE()
Esta debilidad en el tipeo es una especie de bendición mezclada. Debido a que Visual FoxPro es un lenguaje orientado a datos, tiene sentido permitir que las variables (especialmente matrices) sean de débil tipeo para que los datos se puedan transferir libremente entre las tablas y la memoria. Sin embargo, esto requiere un proceder más disciplinado por parte de los desarrolladores para evitar la confusión al trabajar con el código. Está fuertemente recomendada la adopción de la convención de nombres. La convención utilizada más frecuentemente es aquella en la que los dos primeros caracteres de las variables indican su alcance y el tipo de dato a guardar, como se muestra a continuación:

Identificador
de alcance
Utilizado para Identificador
de tipo
Utilizado para
g Public (= Global) c Character
p Private n Numeric (puede ser Decimal o Integer)
(i,f,d,b)* Numeric especiales (Integer, Float, Double, Binary)
l Local d Date
t Parameter (Private o local) t DateTime
l Logical (Boolean)
y Currency
(m) ** Memo
o Referencia de objeto
a Array (matriz)
u No especificado o desconocido
* VFP no distingue internamente entre estos tipos - todos se implementan como "números".  Sin embargo con orígenes de datos que los distinguen (por ejemplo, SQL Server) es muy útil identificar el tipo original.
** Aunque no es estrictamente un tipo de datos, se utiliza comúnmente para indicar una variable específica cuyo objetivo es guardar el contenido de un campo memo.
Continua en "Alcance en Visual FoxPro - Parte 2"

1 comentario :

Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.