Árvore de páginas

Los Bloques de código constituyen un poderoso recurso del AdvPL. Permiten la exportación de pequeños pedazos de código ejecutable de un lugar a otro dentro de la aplicación. El AdvPL trata los bloques de código como valores de datos, permitiendo de esta manera que puedan almacenarse en variables, pasados como argumentos a funciones y utilizarse como una alternativa más eficiente para el operador macro ( & ).

 

Definición

 

La sintaxis utilizada para la definición de un bloque de código es:

 

{ | [ <lista de argumentos> ] | <lista de expresiones> }

 

Los argumentos ( <lista de argumentos> ) y las expresiones ( <lista de expresiones> ) deben separarse por comas. Las expresiones especificadas no pueden contener comandos, estructuras de control del flujo de programación (WHILE ... ENDDO, IF ... ENDIF, etc.) o declaraciones (LOCAL, PRIVATE, etc.).

 

Las barras verticales ( | | ), que delimitan la lista de argumentos de los bloques de código, son obligatorias, aunque no existan argumentos. A continuación, listamos algunos ejemplos de bloques de código:

{ | | “Bloque sin argumentos” }
{ | x | x + 1 }
{ | a, b | Func1(a) + Func2(b) }
{ | i, j, k | Func(i), Func(j), Func(k) }

 

Como se dijo anteriormente, un bloque de código puede atribuirse a una variable o elemento de array por medio del operador en línea ( := ).

 

Ejecución de bloques de código

 

La ejecución o evaluación del resultado de los bloques de código se realiza por la función EVAL(), cuya sintaxis es:

 

EVAL( <bloque de código>, <lista de parámetros> )

 

La función EVAL() ejecuta el bloque de código especificado ( <bloque de código> ), pasándole los argumentos contenidos en la lista de parámetros ( <lista de parámetros> ). Las expresiones contenidas en el bloque de código se ejecutan y evalúan una por una, de izquierda a derecha. El valor resultante del bloque de código será el resultado de la última expresión. Por ejemplo:

bCodBloc := { | nNum1, nNum2 | nNum1 * nNum2 }
 
MSGALERT( EVAL(bCodBloc, 2, 3) )

 

El resultado de la expresión anterior será 6.

 

Además de la función EVAL(), las funciones AEVAL() y DBEVAL() también ejecutan bloques de código. Estas funciones procesan, respectivamente, arrays y archivos de datos, ejecutando el bloque de código especificado para cada elemento del array o registro del archivo de datos.

 

Utilización de bloques de código

 

Los bloques de código se utilizan particularmente en la implementación de rutinas flexibles, es decir, que puedan ejecutarse independientemente del tipo de dato pasado a éstas.

 

El siguiente ejemplo muestra la función Mensaje sin la utilización de bloques de código. En este caso, la función depende del tipo de dato pasado.

// Muestra un dato en la pantalla, por una determinada cantidad de veces.
FUNCTION Mensagem(xDado, nVezes)

	LOCAL nRepet := 0

	IF VALTYPE(xDado) == "C"
	// Dato del tipo carácter
		xDado := xDado

	ELSEIF VALTYPE(xDado) == "N"
	// Dato del tipo numérico
		xDado := LTRIM(STR(xDado))

	ELSEIF VALTYPE(xDado) == "D"
	// Dato del tipo fecha
		xDado := DTOC(xDado)

	ELSEIF VALTYPE(xDado) == "L"
	// Dato del tipo lógico
		xDado := IIF(xDado, "Verdadero", "Falso")

	ELSE
	// Otro tipo de dato
		xDado := "Indefinido"
	ENDIF

	FOR nRepet := 1 TO nVezes
		MSGALERT(xDado)
	NEXT nRepet

RETURN

 

Para dejar la función Mensaje más genérica, independientemente del tipo de dato pasado, podrían utilizarse los siguientes bloques de código:

bCarCod   := { | xDado | xDado }
bNumCod   := { | xDado | LTRIM(STR(xDado)) }
bLogCod   := { | xDado | IF(xDado, “Verdadero”, “Falso”) }
bDatCod   := { | xDado | DTOC(xDado) }

 

Pasando los bloques de código definidos anteriormente, la función Mensaje podría tener la siguiente forma:

// Muestra un dato en la pantalla, por una determinada cantidad de veces.
FUNCTION Mensagem(xTexto, bBloco, nVezes)


LOCAL nRepet := 0


FOR nRepet := 1 TO nVezes
          MSGALERT(EVAL(bBloco, xTexto))
NEXT nRepet


RETURN

 

Por lo tanto, una de las utilizaciones básicas de los bloques de código es al pasar parámetros a funciones que traten genéricamente los datos, dejándolos de esta manera, más flexibles e independientes, pues se ejecutan de acuerdo con el bloque de código pasado.

 

La utilización de bloques de código es un importante recurso del lenguaje AdvPL. A medida que nos familiarizamos con este recurso, queda más simple y fácil de entenderse y utilizarse. Cuando queda bien comprendido y utilizado, el bloque de código deja el código fuente más genérico, flexible y modular, aumentando la productividad en el mantenimiento y en el desarrollo de nuevos programas.

 

Almacenamiento de bloques de código

 

Los bloques de código no pueden almacenarse directamente en campos de archivos de datos, a menos que se transformen en variables del tipo carácter. Para utilizarlos posteriormente, se utiliza el operador macro ( & ), de acuerdo con el siguiente ejemplo:

FUNCTION Mensagem()

LOCAL bBloco := “”

// Graba el bloque de código en el campo de la Tabla SE2 (Título por pagar) como una variable carácter
SE2->E2_TEXTO := “ { |xDado| Func1(xDado) } ”

// Atribuye el bloque de código a la variable bBloco
bBloco := &(SE2->E2_TEXTO)

// Ejecuta el bloque de código almacenado en la variable bBloco
EVAL(bBloco, xDado)


RETURN NIL

 

 

  • Sem rótulos