Cargando



Funciones en Lua

En este tutorial aprenderemos como es el manejo de las funciones en Lua, pasando por su definición y abordando algunas características no convencionales de las mismas en el lenguaje.


jul 16 2015 11:01
Profesional
Las funciones son el mecanismo principal para la abstracción de las declaraciones y expresiones en Lua, estas pueden llevar a cabo tareas específicas, las cuales son llamadas la mayoría de las veces procedimientos o subrutinas en otros lenguajes.

Las funciones la mayoría de las veces son escritas con paréntesis y una lista de argumentos que permitirán a la misma realizar una acción en específico, donde puede darse caso que estas funciones no necesiten argumentos, sin embargo los paréntesis deben especificarse, veamos un ejemplo de funciones que usamos como expresiones dentro de Lua:

funciones_lua.jpg


Como vemos pudimos utilizar funciones de ambas formas descritas, pero existe un caso especial que es donde la función posee un solo argumento y ese argumento es un string literal o un constructor para una tabla o arreglo, en este caso los paréntesis son opcionales, veamos:
print "Hola Mundo" <--> print("Hola Mundo")
dofile 'archivo.lua' <--> dofile ('archivo.lua')
print [[arreglo multi-line msj]] <--> print([[arreglo multi-line msj]])
f{var1=17, var2=30} <--> f({var1=17, var2=30})
type{} <--> type({})
De acuerdo al ejemplo pudimos escribir las funciones de ambas formas, siendo estas igualmente válidas.

Definiendo funciones


Un programa en Lua puede usar funciones definidas tanto en C como en el propio lenguaje, por ejemplo, todas las funciones estándar en la librería de Lua son escritas en C, lo cual no es relevante para los desarrolladores, ya que la invocación de ambas no posee diferencia alguna.

Sabiendo esto la definición no discrepa de otros lenguajes, la sintaxis convencional de una función se rige por el nombre de la función, una lista de parámetros y el cuerpo de la función, el cual es una lista de declaraciones, veamos un ejemplo para ilustrar lo explicado:
function operacion (var)
local sum = 0
sum = var + 6
return sum
end
Ya tenemos nuestra función, sin embargo de esa forma no tiene mucha utilidad, ya que necesita ser invocada enviando el parámetro que necesita, para eso podemos agregar una línea más a nuestro código para invocar a la misma:
function operacion (var)
local sum = 0
sum = var + 6
return sum
end

print(operacion(57))
Si ejecutamos nuestro ejemplo en nuestra terminal podremos ver como nuestro programa recibe el parámetro y de acuerdo a las operaciones definidas dentro de nuestra función nos devuelve un valor:


Algo que podemos destacar de las funciones en Lua, es que los parámetros funcionan como variables locales, ya que son inicializadas con los valores que reciben en la llamada de la función. Además de esto podemos invocar una función con un número distinto de argumentos definidos en la función, Lua se adapta a esto de manera que lo hace con la asignación múltiple, tema que abordamos en el tutorial pasado, donde los argumentos extras son descartados y los parámetros extras obtienen el tipo de valor nil, por ejemplo imaginemos que tenemos la siguiente función:
function funcion_multiple(a, b) return a or b end
Veamos como en la siguiente porción código llamamos a la función con distintos parámetros y del lado derecho como es realizada la asignación:
f(8)			  <-->   a=8, b=nil
f(8, 15)	    <-->   a=8, b=15
f(8, 15, 4)    <-->   a=8, b=15 (El valor 4 es descartado)
Aunque este comportamiento puede llevar a errores de programación, también es útil, especialmente para argumentos por defecto.

Múltiples resultados


Una característica no convencional pero bastante útil de Lua, es la capacidad de retornar múltiples resultados, incluso funciones predefinidas del lenguaje pueden hacer esto. Un ejemplo de esto es la función string.find, la cual busca un patrón de ocurrencia en una cadena dada, esta función retorna dos índices, el primero es el índice donde este patrón inicia y el segundo es donde termina, veamos un ejemplo práctico del uso de esta función que podemos hacer perfectamente en nuestra consola interactiva:

funciones_lua-3.jpg


Las funciones que escribimos en Lua también pueden retornar múltiples resultados, para ello solamente debemos listarlos luego de nuestro retorno, veamos un ejemplo donde creamos una función para localizar el mayor de una lista de elementos en un arreglo y su posición en la misma:
function maximovalor (a)
local minimo = 1

local m = a[minimo]

for i,val in ipairs(a) do
if val > m then
minimo = i; m = val
end
end
return m, minimo
end
print(maximovalor({8,10,23,12,5}))
Como vemos nuestra función es bastante sencilla y en nuestro retorno devuelve dos valores, que en este caso de acuerdo a lo que estamos enviando deberíamos devolvernos 23 como mayor número y 3 como la posición, veamos:


Número variable de argumentos


Además de la funcionalidad de retornar múltiples resultados, Lua también puede recibir un número variable de argumentos, por ejemplo a lo largo de los tutoriales hemos usado la función print con uno, dos y hasta tres argumentos, es decir, la misma puede recibir un número variable de argumentos, pero así como lo hace esta, también lo pueden hacer las funciones que desarrollemos en Lua, veamos un ejemplo de esto:
function funcion_ejemplo (...)
local s = 0
for i, v in ipairs{...} do
s = s + v
end
return s
end
print(funcion_ejemplo(8, 19, 30, 14, 10))
Si somos observadores en la definición de nuestra función tenemos tres puntos (…) dentro de los paréntesis, esto indica que nuestra función acepta un número variable de argumentos, y cuando la función es llamada todos los argumentos enviados son recolectados internamente y luego ser procesados con la función ipairs, veamos la salida de nuestra función la cual se encarga de sumar todos los argumentos enviados a la misma:


Como vemos esta característica de Lua es bastante útil ya que nos permite definir nuestra función sin tener un conocimiento de cuantos argumentos le vamos a pasar a la misma, incluso podemos decir que esta funcionalidad se asemeja un poco a lo que se hace con los prepared statements para manejar operaciones con Base de Datos en lenguajes como PHP o Java.

Nombrar argumentos


El envío de argumentos en Lua es posicional, es decir, cuando invocamos una función, estos argumentos corresponden a los parámetros de acuerdo a sus posiciones, el primer argumento corresponde al primer parámetro y así consecutivamente, aunque algunas veces no nos vendría mal especificar los argumentos por nombre.

Esta funcionalidad es similar a los argumentos variables, sin embargo al definir los nombres para nuestros argumentos, el manejo de los mismos es mucho más sencillo, donde con solo utilizar una tabla o arreglo podemos hacer esta funcionalidad, algo que es muy útil si nuestra función utiliza algunos de estos parámetros de manera opcional, veamos el siguiente llamado a una función que recibe una cierta cantidad de parámetros para construir una ventana:
crear_ventana{ x=0, y=0, ancho=0, alto=200,
titulo = 'Ventana Lua', fondo="blue",
bordes = true
}
De esta forma la función crear_ventana tiene la libertad de verificar estos argumentos por nombre si así lo desea, veamos como recibimos estos argumentos en nuestra función y que podemos hacer con la misma:
function crear_ventana (opciones)

-- verifica las opciones obligatorias
if type(opciones.titulo) ~= "string" then
error("sin titulo")
elseif type(opciones.ancho) ~= "number" then
error("sin medida de anchura")
elseif type(opciones.altura) ~= "number" then
error("sin medida de altura")
end

-- aplicamos las opciones
crear_ventana(opciones.titulo,
opciones.x or 0,
opciones.y or 0,
opciones.ancho, opciones.altura,
opciones.fondo or "white",
opciones.bordes
)
End
Como vemos las posibilidades en nuestros programas son mucho mayores con esta funcionalidad, y a pesar que este ejemplo es ilustrativo nos permite ver de qué forma podemos aplicar los argumentos con nombres dentro de nuestras funciones.

Así finalizamos este tutorial, donde aprendimos como es el manejo de las funciones en Lua, pasando desde la sintaxis convencional que podemos encontrar en otros lenguajes hasta las características propias del lenguaje como los múltiples resultados, argumentos variables y la posibilidad de nombrar los argumentos que enviemos a nuestras funciones. De esta forma sumando mucho más poder a nuestros programas al incluir este tipo de características y manteniendo la simplicidad a la que Lua nos tiene acostumbrados.

¿Te ayudó este Tutorial?


Sin comentarios, sé el primero!

No esperes más y entra en Solvetic
Deja tus comentarios y aprovecha las ventajas de la cuenta de usuario ¡Únete!

X