Hola! aquí me tienen nuevamente aportando con esta tercera entrega de mi tutorial =D.
Esta vez veremos otro tipo de variable, las de tipo function (función). Para saber más sobre las funciones, continúa leyendo.
Estas pueden ser declaradas de varias formas, como por ejemplo:
function funcion1([argumentos]) BLOQUE end funcion2 = function ([argumentos]) BLOQUE end variable = {true,2,function ([argumentos]) BLOQUE end}
En este ejemplo, al tratarse de funciones cortas he ubicado todo en una sola línea, pero también se puede hacer tranquilamente:
function funcion1([argumentos]) BLOQUE end
Y así para el resto...
Ahora, como se puede observar, he declarado tres variables de tipo function de tres formas distintas:
La primera escribiendo la palabra function seguido del nombre de la variable (funcion1 en nuestro caso) y argumentos opcionales (todo lo que escriba entre "[" y "]" significa que puede ir o no) entre paréntesis, luego el bloque y por último para indicar que termina la declaración de la función, escribimos la palabra end.
Las dos primeras son del mismo tipo, de tal manera que al llamar a las funciones de esta forma: funcion1([argumentos])
y funcion2([argumentos])
es totalmente válido.
El tercer ejemplo, es una variación declarando una función como uno de los elementos de un arreglo, luego para llamar a la función, se usaría variable[3]([argumentos])
, también se pueden usar nombres de variables como se explicó en la anterior entrega.
Bien, también habrán visto alguna vez funciones con este formato: modulo.funcion([argumentos])
, pues para crear funciones de ese tipo primero se crea el modulo como arreglo, el cual contendrá las funciones, de esta forma:
modulo = {} modulo.funcion = function ([argumentos]) BLOQUE end
o también se puede definir como:
function modulo.funcion ([argumentos]) BLOQUE end
En este caso tenemos que la tabla modulo, tiene la función y con esto ya podemos llamar a la función
modulo.funcion([argumentos])
Ahora, ¿por qué se usa a veces un punto y a veces dos puntos?
Bien, como vemos, modulo es una tabla, que puede contener funciones así como otras cosas vistas anteriormente.
Si ejecutamos la función con un punto ".", se ejecutará como estamos acostumbrados a que lo haga con los argumentos que le pasemos, pero si en lugar de un punto "." utilizamos dos puntos ":", el primer argumento de la función será la tabla modulo en sí. Esto quedará más claro con un ejemplo:
personaje = { x = 20, y = 20 } personaje.ancho = 20 personaje.alto = 50 function personaje.muevederecha(personaje, pixeles) personaje.x = personaje.x + pixeles end
Aquí vemos como utilizamos la tabla personaje como primer argumento y la función es creada usando un punto ".", pero si cambiamos el nombre personaje ya no nos funcionaría, porque buscará personaje... Entonces, ¿Cómo podemos hacer que se ejecute sobre sí mismo?
Para eso usamos los dos puntos ":", o con un punto "." y la palabra "self", pero por comodidad usaremos los dos puntos ":" y nos ahorraremos el uso de self como primer argumento ;).
Usando el ejemplo anterior, quedaría así:
function personaje:muevederecha(pixeles) self.x = self.x + pixeles end
Hemos cambiado personaje (que es el nombre de la tabla) por self (que indica que usaremos la misma tabla como argumento), de tal manera que se hace más cómodo de utilizar, ya que podremos hacer personaje:muevederecha(20)
y al ejecutarse, personaje.x tomará el valor de 40 (20 + 20).
Bueno, espero me sigan hasta ahí, ahora veremos los dos tipos de funciones que hay:
La primera es un tipo de función que no retorna valor alguno, estas sirven más que nada, para simplificar procesos, es decir, si tenemos una parte de código que se repite varias veces en nuestro programa, podemos poner ese trozo de código en una función y luego llamamos a la función, como ejemplo pondré una función sencilla:
function mostrar_suma(a,b) print(a+b) -- la función print es genérica de lua, en los luaplayers para PSP se usan funciones diferentes dependiendo del luaplayer end
Esa función toma los argumentos a y b (nótese que van separados por una coma) y luego muestra como resultado la suma, quiere decir que al hacer mostrar_suma(2,3)
mostrará 5.
Otro ejemplo sería:
function hello() print("Hello world!") end
Esa función no necesita de argumentos, y al hacer hello()
mostrará el mensaje "Hello world!"
El otro tipo de función retorna un valor, esto puede ser también con o sin argumentos, dependiendo de lo que esté programado dentro de esa función.
function suma(a,b,c) return a+b+c end
Esta es una función que retorna el valor de la suma de sus tres argumentos a, b y c, luego el return hará que la función tome el valor de lo que está luego de dicha palabra, de tal manera que si se hace:
resultado = suma(2,3,1)
El valor almacenado en resultado, será 6
Otro ejemplo, pero esta vez sin argumentos:
function mensaje() return "Hola mundo!" end
mensaje()
tomará el valor de lo que se escriba luego del return dentro de esta función, es decir, si se hace un print(mensaje())
, imprimirá el mensaje "Hola mundo!"
Noten que las funciones mostrar_suma()
y hello()
no tienen un valor de retorno (return), por eso al hacer:
variable = mostrar_suma() variable2 = hello()
variable y variable2 serían de tipo nil (nulo), ya que no hay dato que podamos almacenar, además sería lo mismo que hacer
mostrar_suma() hello()
Nota: Para las funciones que usen argumentos, se les puede pasar más argumentos que la cantidad que necesitan, pero es innecesario ya que no hace nada con esos valores.
En cambio si se le pasan menos argumentos de los que necesitan, dará error, ya que en el código interno de la función habrán valores de tipo nil y no podrá realizar el código, salvo el caso de que el código interno use sus argumentos como valores booleanos (lo veremos más adelante en estructuras de control, sobre todo las condicionales).
Bien, como he dicho en la nota de arriba, si no le pasamos los argumentos que necesita la función, dará error de que faltan parámetros. Pero… y si queremos hacer una función que tenga 1, 2, 3 o ningún parámetro?
La solución sería usar argumentos variables que en Lua se los define con tres puntos "..."
Veamos un ejemplo:
function sumatotal(...) a, b, c = ... res = 0 if a then res = res + a end if b then res = res + b end if c then res = res + c end return res end
En esta función especificamos que queremos tres argumentos opcionales a, b y c y los llenamos con los parámetros recibidos mediante los tres puntos "..." de tal manera que las variables pueden ser nil o un valor, dependiendo si se ha pasado el argumento o no.
Aquí también vemos como se usan las variables como valores booleanos, me explico:
Si las variables existen (no son nil y tampoco son false) hará la suma entre res y dicha variable (esto ya lo tendrán más claro en la entrega "Estructuras de control"), de tal manera que si se hace variable = sumatotal(3,nil,4)
, variable tendría el valor de 7.
Veamos otro ejemplo:
function sumatotal(...) lista_args = {...} local res = 0 for i = 1, #lista_args do if lista_args[i] then res = res + lista_args[i] end return res end
En esta función se ha hecho algo similar que la anterior, pero esta vez creando una lista con los argumentos recibidos y se ha hecho un for para ir sumando. En esta función al hacer variable = sumatotal(3,nil,4)
, variable será 3
¿Cómo?, pues recordemos que el operando de longitud "#" cuenta los elementos hasta encontrar un índice vacío (nil), en este caso el segundo argumento, así que hay que tener cuidado sobre elegir una estructura u otra.
Saludos!
Tutoriales realizados con la ayuda y asesoramiento de DeViaNTe.
Cualquier duda o sugerencia, comenten =)
Comentarios
Mui buen tuto sea agradece
Mui buen tuto sea agradece !!! ;)
gracias saludoss
Me tomé la libertad de poner
Me tomé la libertad de poner link en ICON0. Excelente Tuto Don Chime.
Saludos!!!
Tremendos tutoriales...
Hola Chimecho,
Sólo quería felicitarte por los excelentes tutoriales que haces, porque la verdad, están explicados de una forma muy clara...
Un saludo ;-)
Para recibir ayuda por parte de otros usuarios más rápidamente, recomendamos que pongas títulos descriptivos y no utilices abreviaturas (estilo MSN) en tus post de los foros. Recuerda que accediendo al Manual del perfecto forero y las Normas de la Comunidad aprenderas trucos para resolver tus dudas antes.
No preguntes por MP, mejor pregunta aquí.
El priment ! :P
El priment ! :P Bueno solo queria agradecerte por estos magnificos tutoriales, que, en quanto tenga tiempo los leere, ya que algun dia me gustaria ser como tu o m0skit0 ( no sus riais ¬¬)
Bueno, hasta otra ! ^^
"Debería haber un Gran Almacén de Arte al que el Artista pudiera llevar sus Obras y desde el cual el Mundo pudiera tomar lo que necesitara"
Ludwig van Beethoven