Funciones

Las funciones son un elemento básico de la programación: Son una forma conveniente y poderosa de agrupar declaraciones que realizan una tarea. Son la interfaz entre el dispositivo Citrix ADC y el código de extensión. En el caso de las directivas, defina funciones de extensión de directivas. Para los protocolos, se implementan funciones de devolución de llamada para los comportamientos de protocolo. Las funciones consisten en definiciones de funciones que especifican qué valores se pasan dentro y fuera de la función y qué sentencias se ejecutan para la función, y llamadas a funciones, que ejecutan funciones con datos de entrada específicos y obtienen resultados de la función.

Funciones de devolución de llamada de comportamiento de protocolo

El comportamiento del cliente TCP consiste en una función de devolución de llamada (on_data) que procesa eventos de flujo de datos del cliente TCP. Para implementar Equilibrio de carga basado en mensajes (MBLB) para un protocolo basado en TCP, puede agregar código para esta función de devolución de llamada para procesar la secuencia de datos TCP desde el cliente y analizar la secuencia de bytes en mensajes de protocolo.

Las funciones de devolución de llamada en un comportamiento se llaman con un contexto, que es el estado del módulo de procesamiento. El contexto es la instancia del módulo de procesamiento. Por ejemplo, las devoluciones de llamada del comportamiento del cliente TCP se llaman con contextos diferentes para diferentes conexiones TCP de cliente.

Además del contexto, las devoluciones de llamada de comportamiento pueden tener otros argumentos. Por lo general, el resto de los argumentos se pasan como carga útil, que es la colección de todos los argumentos. Por lo tanto, las instancias del módulo de procesamiento programable se pueden ver como una combinación de estado de instancia más funciones de devolución de llamada de evento, es decir, el contexto más comportamiento. Y el tráfico fluye a través de la proceso como carga útil de eventos.

Prototipo de función de devolución de llamada del cliente TCP:

                           Cliente de función on_data (ctxt, carga útil)

                                            //.código

            end

donde,

  • ctxt: Contexto de procesamiento de cliente TCP
  • payload: Carga de evento
    • payload.data: Datos TCP recibidos, disponibles como una secuencia de bytes

Funciones de extensión de directivas

Dado que el lenguaje de expresión de directiva de NetScaler está fuertemente escrito, la definición de una función de extensión debe especificar los tipos de sus entradas y su valor devuelto. La definición de la función Lua se ha ampliado para incluir estos tipos:

function self-type:function-name(parameter1: parameter1-type, etc.): return-type
     statements
end

where,

the types are NSTEXT, NSNUM, NSBOOL, or NSDOUBLE.

self-type es el tipo del parámetro self implícito que se pasa a la función. Cuando se utiliza la función de extensión en una expresión de directiva Citrix ADC, este es el valor generado por la expresión situada a la izquierda de la función. Otra forma de ver esto es que la función extiende ese tipo en el lenguaje de directivas de Citrix ADC.

Los tipos de parámetros son los tipos de cada parámetro especificado en la llamada a la función de extensión en la expresión de directiva. Una función de extensión puede tener cero o más parámetros.

return-type es el tipo del valor devuelto por la llamada a la función de extensión. Será la entrada a la parte de la expresión de directiva, si la hay, a la derecha de la función, o bien es el valor del resultado de la expresión.

Ejemplo:

function NSTEXT:COMBINE_HEADERS() : NSTEXT

Uso de la función de extensión en una formulación de directivas:

HTTP.REQ.FULL_HEADER.AFTER_STR("HTTP/1.1rn").COMBINE_HEADERS()

Aquí el parámetro self es el resultado de HTTP.REQ.FULL_HEADER.AFTER_STR (“HTTP/1.1RN”), que es un valor de texto. El resultado de la llamada COMBINE_HEADERS () es texto, y como no hay nada a la derecha de esta llamada, el resultado de toda la expresión es texto.

Definición de función local

Además de las funciones de extensión, no se pueden definir funciones globales en un archivo de extensión. Pero las funciones locales se pueden definir dentro de las funciones de extensión mediante la instrucción normal de la función Lua. Esto declara el nombre de la función y los nombres de sus parámetros (también conocidos como argumentos), y como todas las declaraciones en Lua, no especifica ningún tipo. La sintaxis para esto es:

local function function-name(parameter1-name, parameter2-name, etc.)
     statements
end

Todos los nombres de funciones y parámetros son identificadores. (El nombre de la función es en realidad una variable y la declaración de función es la abreviatura de nombre de función local = función (parámetro1, etc.), pero no tiene que entender esta sutileza para usar funciones.)

Tenga en cuenta que etc. se utiliza aquí para la continuación del patrón de nombres de parámetros en lugar del habitual…. Esto se debe a que… en realidad significa una lista de parámetros variables, que no se discutirá aquí.

Cuerpo de función y retorno

El bloque de sentencias entre la función y las sentencias finales es el cuerpo de la función. En el cuerpo de la función, los parámetros de la función actúan como variables locales, con valores proporcionados por las llamadas a la función, como se describió anteriormente.

La declaración return proporciona valores para ser devueltos a la persona que llama de la función. Debe aparecer al final de un bloque (en una función, si entonces, para bucle, y así sucesivamente; Puede estar en su propio bloque hacer return… end). Puede especificar no, uno o más de un valor devuelto:

return -- returns nil
return expression -- one return value
return expression1, expression2, ... -- multiple return values

Ejemplos:

local function fsum(a)
     local sum = 0
     for i = 1, #a do
          sum = sum + a[i]
     end
     return sum
end

local function fsum_and_average(a)
     local sum = 0
     for i = 1, #a do
          sum = sum + a[i]
     end
     return sum, sum/#a
end

Llamadas a funciones

Una llamada a la función ejecuta el cuerpo de una función, proporcionando valores para sus parámetros y recibiendo resultados. La sintaxis de una llamada a función es nombre-función (expresión1, expresión2, etc.), donde los parámetros de la función se establecen en las expresiones correspondientes. El número de expresiones y parámetros no necesita ser el mismo. Si hay menos expresiones que parámetros, los parámetros restantes se establecen en nil. Por lo tanto, puede hacer que uno o más parámetros al final de la llamada sean opcionales, y su función puede verificar si se especifican verificando si no son nulos. Una forma común de hacer esto es con la operación o:

function f(p1, p2) -- p2 is optional
     p2 = p2 or 0 -- if p2 is nil, set to a default of 0
     . . .
end

Si hay más expresiones que parámetros, se ignoran los valores de expresión restantes.

Como se señaló anteriormente, las funciones pueden devolver varios valores. Estas devoluciones se pueden utilizar en una instrucción de asignación múltiple. Ejemplo:

local my_array = {1, 2, 3, 4}
local my_sum, my_ave = sum_and_average(my_array)

Funciones de iterador y genérico para bucles

Ahora que hemos introducido funciones, podemos hablar de bucles genéricos para. La sintaxis para el bucle genérico for (con una variable) es:

for variable in iterator(parameter1, parameter2, etc.) do
     statements in the for loop body
end

donde iterador () es una función con cero o más parámetros que proporciona un valor para la variable en cada iteración del cuerpo del bucle. La función iterador realiza un seguimiento de dónde está en la iteración mediante una técnica llamada cierre, que no tiene que preocuparse por aquí. Señala el final de la iteración devolviendo nil. Las funciones del iterador pueden devolver más de un valor, para su uso en una asignación múltiple.

Escribir una función iteradora está más allá del alcance de este documento, pero hay una serie de iteradores incorporados útiles que ilustran el concepto. Uno es el iterador pares (), que itera a través de las entradas en una tabla y devuelve dos valores, la clave y el valor de la siguiente entrada.

Ejemplo:

local t = {k1 = "v1", k2 = "v2", k3 = "v3"}
local a = {} -- array to accumulate key-value pairs
local n = 0 -- number of key-value pairs
for key, value in pairs(t) do
     n = n + 1
     a[n] = key .. " = " .. value -- add key-value pair to the array
end
local s = table.concat(a, "; ") -- concatenate all key-value pairs into one string

Otro iterador útil es la función string.gmatch (), que se utilizará en el siguiente ejemplo COMBINE_HEADERS ().