Bienvenidos sean a este post, una consecuencia de las funciones de primera clase es la posibilidad de poder almacenar funciones no solamente en variables globales sino tambien en campos de tablas y variables locales, si bien ya hemos visto algunos ejemplos de funciones en campos de tablas, para poder crear las funciones no globales en Lua solamente debemos unir la expresion que usamos para crear funciones con la que usamos para crear tablas, veamos algunos ejemplos de sintaxis con el primer ejemplo mas basico:

Anuncios
Lib = {} 
Lib.foo = function(x,y) return x + y end 
Lib.goo = function(x,y) return x - y end

Otro ejemplo de sintaxis valida es la siguiente:

Lib = {
	foo = function(x,y) return x + y end,
	goo = function(x,y) return x - y end
}

Y a su vez Lua nos permite un tercer tipo de sintaxis valida:

Lib = {}
function Lib.foo (x,y) return x + y end
function Lib.goo (x,y) return x - y end

Cuando almacenamos una funcion en una variable local esta pasa a ser una funcion local que es una funcion restringida a un cierto rango, tales definiciones son especialemente valiosas para paquetes porque Lua puede manejar cada chunk como una funcion, acarreando como consecuencia que el chunk puede declarar funciones y solo serian visibles dentro del chunk, y esto nos asegura que otras funciones en el paquete puedan usar estas funciones locales, veamos un ejemplo:

Anuncios
local f = function (<parametros>)
	... instrucciones ...
end

local g = function (<parametros>)
	... instrucciones ...
	f()
	... mas instrucciones ...
end

En este caso tenemos dos funciones locales (f y g), primero definimos a f y luego g pero en la funcion g llamamos a f y esta es visible gracias a que pertenecen al mismo paquete, otra forma valida de sintaxis es la siguiente:

local function f (<parametros>)
	... instrucciones ...
end

En este caso indicamos a la funcion como local pero nosotros vamos a tener un inconveniente cuando trabajemos con funciones locales y metodos recursivos, veamos el siguiente ejemplo:

local fact = function(n)
	if n==0 then return 1
	else return n*fact(n-1)
	end
end

Este tipo de codigo nos devolveria un error porque al momento de llamar el codigo en else la funcion fact todavia no fue creada, esto produce que en lugar de buscar una variable local busque una variable global, para resolver este problema debemos actuar de la siguiente forma:

local fact
fact = function(n)
	if n==0 then return 1
	else return n*fact(n-1)
	end
end

En este caso el problema esta solucionado porque fact ya esta declarado de forma local y el resto solamente es la definicion que tendra el mismo y podra ser usado de forma recursiva.

Anuncios
Nota: Recuerden que Lua para utilizar una funcion no global recursiva usa la siguiente sintaxis:

local function nombreFuncion (< parametros >) < cuerpo > end

equivale a usar esta sintaxis:

local ombreFuncion 
nombreFuncion = function (< parametros >) < cuerpo > end

Entonces nosotros podriamos tomar el ejemplo y modificarlo de la siguiente forma y funcionara correctamente:

local function fact(n)
	if n==0 then return 1
	else return n*fact(n-1)
	end
end

Pero esta forma de trabajo no nos va a funcionar si tenemos funciones indirectas recursivas, en tales casos se debe usar el equivalente de una declaracion explicita directa, veamos el siguiente ejemplo:

local f,g

function g ()
	... algun codigo ...
	f()
	... algun codigo ...
end

function f ()
	... algun codigo ...
	g()
	... algun codigo ...
end

En este caso la declaracion explicita directa es: local f, g y cuando definimos a nuestras funciones recuerden no utilizar la palabra local en las definiciones porque esto puede traer como consecuencia que el interprete haga una variable local en lugar de la funcion dejando a la funcion dentro de la otra funcion como undefined (indefinida)

Anuncios

En resumen, hoy hemos visto que es una funcion no global, en que ambito se aplica, las distintas sintaxis, algunos inconvenientes y como solucionarlos, espero les haya sido util sigueme en Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00