Histórico da Página
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:
...
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:
Sem Formato |
---|
{ | | “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:
...
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:
Sem Formato |
---|
bCodBloc := { | nNum1, nNum2 | nNum1 * nNum2 } |
...
...
MSGALERT( EVAL(bCodBloc, 2, 3) ) |
El resultado de la expresión anterior será 6.
...
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.
Sem Formato |
---|
// 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, |
...
ELSE
// Otro tipo de dato
xDado := “Indefinido”
ENDIF
FOR nRepet := 1 TO nVezes
MSGALERT(xDado)
NEXT nRepet
...
"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:
...
Sem Formato |
---|
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:
Sem Formato |
---|
// 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.
...
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:
Sem Formato |
---|
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 |
RETURN NIL