Skip to content

Instantly share code, notes, and snippets.

@UnderABloodySky
Last active July 24, 2020 08:35
Show Gist options
  • Save UnderABloodySky/b269041c4422df3021d409caae89e791 to your computer and use it in GitHub Desktop.
Save UnderABloodySky/b269041c4422df3021d409caae89e791 to your computer and use it in GitHub Desktop.
Lua

LUA

lua_logo

Lua (del portugués, luna) es un lenguaje de código abierto, multiparadigma, imperativo, estructurado y bastante ligero desarrollado por el grupo de Técnología en Computación Gráfica de la Universidad Catolica de Rio de Janeiro (Latin American power), creado sobre el lenguaje de programación C y fue diseñado como un lenguaje interpretado con una semántica extendible. Lua tiene su valor en múltiples plataformas que van desde grandes sistemas de servidores hasta pequeñas aplicaciones móviles. Lua consta de dos partes: la parte del intérprete de Lua y el sistema de software en funcionamiento. El sistema de software en funcionamiento es una aplicación informática real que puede interpretar programas escritos en este lenguaje. El intérprete de Lua está escrito en ANSI C, por lo tanto, es altamente portátil y puede ejecutarse en un amplio espectro de dispositivos, desde servidores de red de alta gama hasta dispositivos pequeños.

Casos de uso:

Algunos posibles casos de uso para Lua son:

  • Programacion de juegos
  • Secuencias de comandos en aplicaciones independientes
  • Scripting en la web
  • Extensiones y complementos para bases de datos como MySQL Proxy, MySQL WorkBench, Redis, entre otros.
  • Sistemas de seguridad como el sistema de detección de intrusiones.

Configuración del entorno local:

  • (a) Editor de texto
  • (b) El intérprete de Lua: Es solo un pequeño programa que le permite escribir comandos Lua y ejecutarlos de inmediato. Detiene la ejecución de un archivo Lua en caso de que encuentre un error, a diferencia de un compilador que se ejecuta completamente.
  • (c) Compilador de Lua : Cuando extendemos L_ua_ a otros lenguajes/aplicaciones, necesitamos un kit de desarrollo de software con un compilador que sea compatible con la interfaz del programa de aplicación Lua.

Instalación:

En Linux: Para descargar y compilar Lua, use el siguiente comando

wget http://www.lua.org/ftp/lua-x.y.z tar.gz
$ tar zxf lua-x.y.z.tar.gz
$ cd lua-x.y.z
$ make linux test

Actualmente la version es 5.4.0

Ejemplos:

El infaltable Hello World:

Tenemos un archivo llamado jelouGorl.lua con el siguiente fragmento de código:

print("Jelou Gorl!")

Para poder correrlo solo debemos, posicionados dentro de la carpeta que contiene al archivo jelouGorl.lua, tipear dentro la consola el siguiente comando:

lua jelouGorl.lua

Comentarios:

--[[ Hola, soy un comentario. Al menos llegue más lejos que mi padre. --]]
-- Este tambien es un comentario
--[[... Oh no quien soy?]]

Identificadores:

Un identificador de Lua es un nombre utilizado para identificar una variable, función o cualquier otro elemento definido por el usuario. Un identificador comienza con una letra "A a Z" o "a a z" o un guión bajo "‘ _ "seguido de cero o más letras, guiones bajos y dígitos (0 a 9). Lua no permite caracteres de puntuación como @, $ y % dentro de los identificadores. Lua es un lenguaje de programación sensible a mayúsculas y minúsculas.

Palabras clave:

La siguiente lista muestra algunas de las palabras reservadas en Lua. Estas palabras reservadas no pueden usarse como constantes o variables o cualquier otro nombre identificador.

  • and
  • break
  • do
  • else
  • elseif
  • end
  • false
  • for
  • function
  • if
  • in
  • local
  • nil
  • not
  • or
  • repeat
  • return
  • then
  • true
  • until
  • while

Variables:

Una variable no es más que un nombre dado a un área de almacenamiento que nuestros programas pueden manipular. Puede contener diferentes tipos de valores, incluidas funciones y tablas. En Lua, aunque no tenemos tipos de datos variables, tenemos tres tipos basados en el alcance de la variable.

  • Variables globales: Todas las variables se consideran globales a menos que se declare explícitamente como local.
  • Variables locales: Cuando el tipo se especifica como local para una variable, su alcance se limita con las funciones dentro de su alcance.
  • Campos de tabla: Este es un tipo especial de variable que puede contener cualquier cosa excepto nula, incluidas las funciones.

Definición Variable en Lua

Una definición de variable significa decirle al intérprete dónde y cuánto crear el almacenamiento para la variable. Una definición de variable tiene un tipo opcional y contiene una lista de una o más variables de ese tipo de la siguiente manera:

type variable_list;

Aquí, type es opcionalmente local o type especificado por lo que es global, y variable_list puede consistir en uno o más nombres de identificadores separados por comas. Aquí se muestran algunas declaraciones válidas:

local    i, j
local    i
local    a,c

Para asignar un valor a tales variables se respeta la sintaxis:

type variable_list = value_list;

Asi mismo estas son asignaciones válidas:

local d , f = 8 ,16  
local d = 16  
local d, f = 8

Detalle de color: una vez inicializadas, es posible hacer este swamping de valores

a, b = b ,a

Lvalues and Rvalues:

Hay dos tipos de expresiones en Lua:

  • lvalue: Las expresiones que se refieren a una ubicación de memoria se llaman expresiones "lvalue". Un valor l puede aparecer como el lado izquierdo o derecho de una tarea.
  • rvalue: El término rvalue se refiere a un valor de datos que se almacena en alguna dirección en la memoria. Un valor r es una expresión que no puede tener un valor asignado, lo que significa que un valor r puede aparecer en el lado derecho, pero no en el lado izquierdo de una asignación.

Las variables son valores y, por lo tanto, pueden aparecer en el lado izquierdo de una tarea. Los literales numéricos son valores y, por lo tanto, no se pueden asignar y no pueden aparecer en el lado izquierdo. Lo siguiente es una declaración válida:

Tipos de datos:

  • nil: Se usa para diferenciar el valor de tener algunos datos o ninguno (misma idea que null).
  • boolean
  • number: Representa números reales (punto flotante de precisión doble).
  • string
  • function: Representa un método escrito en C o Lua.
  • userdata: Datos arbitrarios del usuario.
  • thread: Representa hilos de ejecución independientes y se usa para implementar corutinas.
  • table: Representa matrices ordinarias, tablas de símbolos, conjuntos, registros, gráficos, árboles, etc. Implementa matrices asociativas. Puede contener cualquier valor (excepto nulo).

Operadores matematicos:

>= <= == < >    --[[ Los usuales --]]
~=              --[[ Comprueba si el valor de dos operandos es igual o no, si los valores no son iguales, la condición                                       se vuelve verdader --]]

Operadores lógicos:

and or not --[[ Este último tambien puede ser ! --]]

Operadores diversos:

..      --[[ Concatenar 2 strings --]]
#       --[[ Un operador unario que devuelve la longitud de una cadena o una tabla. --]]

El tema de la prioridad es como se esperaria, de izquierda a derecha, con algunas operaciones que tienen mayor presedencia sobre otras.

Loops:

  • while
  • for
  • repeat...until loop: Repite la operación del grupo de sentencias hasta que se cumpla la condición.
while condition do
  -- Hago algo
end

repeat
  -- Hago cosas
until condition

for i = first, last, delta do 
  -- Idem
end

IF:

function square(iteratorMaxCount,currentNumber)

   if currentNumber<iteratorMaxCount
   then
      currentNumber = currentNumber+1
      return currentNumber, currentNumber*currentNumber
   end
end

Funciones:

La forma general de una definición de método en Lua es la siguiente:

optional_function_scope function function_name( argument0, argument1, argument2, ..argumentN)
function_body
return result_params_comma_separated
end

Para llamarla, se le pasan los valores a la funcion entre parentesis, separados por coma:

ejemplo(valor0, valor1, valor2 ... valorN)

Un posible ejemplo seria esta definición de la función factorial:

function factorial(n)
  local x = 1
  for i = 2, n do
    x = x * i
  end
  return x
end

Caracteres especiales:

Iguales a C, se agregan un par.

Manejo de strings:

string.upper (argumento)

Devuelve una representación en mayúscula del argumento.

string.lower (argumento)

Devuelve una representación en minúscula del argumento.

string.gsub (mainString, findString, replaceString)

Devuelve una cadena al reemplazar las ocurrencias de findString con replaceString.

string.find (mainString, findString,
optionalStartIndex, optionalEndIndex)

Devuelve el índice inicial y el índice final de findString en la cadena principal y nulo si no se encuentra.

string.reverse (arg)

Devuelve una cadena invirtiendo los caracteres de la cadena pasada.

string.format (...)
dia = 24; mes = 07; año = 2020
print(string.format("fecha : %00d/%01d/%02d", dia, mes, año))
print(string.format("Formatenado: %s %s",string0,string1))

Devuelve una cadena con formato. Recuerda un poco a Python o al ${} de Kotlin.

string.char (arg) y string.byte (arg)

Devuelve representaciones numéricas internas y de caracteres del argumento de entrada.

string.len (arg)

Devuelve una longitud de la cadena pasada.

string.rep (cadena, n))

Devuelve una cadena repitiendo la misma cadena n número de veces.

string.char(index)

Devuelve el codigo ASCII del numero pasado por parametro indexs en caso de existir.

Colecciones:

Una dimension::

persistiendoLaCuarentena = {"Fede", "Horacio", "Matias, "Nelson"}

for i = 0, 3 do
   print(persistiendoLaCuarentena[i])
end

Multi dimensión:

array = {}

for i=1,3 do
   array[i] = {}
	
   for j=1,3 do
      array[i][j] = i*j
   end
	
end

-- Accessing the array

for i=1,3 do

   for j=1,3 do
      print(array[i][j])
   end
	
end

Tables:

Los tables se denominan objetos y no son valores ni variables. Lua usa una expresión de constructor {} para crear una tabla vacía. Se debe saber que no existe una relación fija entre una variable que contiene la referencia de la tabla y la tabla misma.

--Inicializo:
unaTabla = {}
-- Asigno:
unaTabla[1]= "Lua"
-- El garbage collector hara de las suyas...
unaTabla = nil

Algunas operaciones pertinentes para las tablas son:

table.concat (tabla [, sep [, i [, j]]])

Concatena las cadenas en las tablas según los parámetros dados.

table.insert (tabla, valor [pos,])

Inserta un valor en la tabla en la posición especificada.

table.maxn (tabla)

Devuelve el índice numérico más grande.

table.remove (tabla [, pos])

Elimina el valor de la tabla.

table.sort (tabla [, comp])

Ordena la tabla según el argumento del comparador opcional.

Modulos:

  • Asumiendo que tenemos un modulo llamado printFormatter
-- Ya que estamos asumiendo, supongamos que printFormatter tiene una funcion llamada simpleFormat(arg)
-- Estoy programando con imaginacxion... Yo estoy debugeando, yo estoy pasando corriendo los tests... (?)

require "printFormatter"
printFormatter.simpleFormat("test")

Lua ha proporcionado una función de alto nivel llamada require para cargar todos los módulos necesarios. Se mantiene lo más simple posible para evitar tener demasiada información en el módulo para cargarlo. La función require solo asume los módulos como un fragmento de código que define algunos valores, que en realidad son funciones o tablas que contienen funciones.

Metatabla:

Una metatabla es una tabla que ayuda a modificar el comportamiento de una tabla a la que se adjunta con la ayuda de un conjunto de claves y métodos relacionados. Estos meta métodos son potentes funciones de Lua que permiten funciones como:

  • Cambio / adición de funcionalidades a operadores en tablas.
  • Buscar metatables cuando la clave no está disponible en la tabla usando __index en metatable.
  • Hay dos métodos importantes que se utilizan para manejar metatablas que incluyen:
    • setmetatable (table, metatable) - Este método se usa para establecer metatable para una tabla.
    • getmetatable (table) - Este método se usa para obtener metatabla de una tabla.

Primero veamos cómo establecer una tabla como metatabla de otra. Se muestra a continuación.

miOtraTabla = {}
miMetaTabla = {}
setmetatable(miOtraTabla, miMetaTabla)

El código anterior se puede representar en una sola línea como se muestra a continuación.

miOtraTabla = setmetatable({},{})

A continuación se muestra un ejemplo simple de metatabla para buscar la misma cuando no está disponible en la tabla.

miOtraTabla = setmetatable({key1 = "value1"}, {
   __index = function(mytable, key)
      if key == "key2" then
         return "metatablevalue"
      else
         return mytable[key]
      end
   end
})

La tabla miOtraTabla en este último ejemplo es {key1 = "value1"}. Metatable está configurado para que miOtraTabla que contiene una función para __index, que llamamos como metametodo. Este hace un trabajo simple de buscar un índice "clave2", si se encuentra, devuelve "metatablevalue", de lo contrario, devuelve el valor de miOtraTablae para el índice correspondiente. Existe una gran cantidad de metametodos. Para más información al respecto considerar consultar el siguiente link

Lua en el cielo con Objetos

OOP en Lua

Puede implementar la orientación a objetos en Lua con la ayuda de tablas y funciones de primer orden de Lua. Al colocar funciones y datos relacionados en una tabla, se forma un objeto. La herencia se puede implementar con la ayuda de metatablas, proporcionando un mecanismo de búsqueda de funciones (métodos) y campos inexistentes en los objetos principales. Las tablas en Lua tienen las características de un objeto como estado e identidad que es independiente de sus valores. Dos objetos (tablas) con el mismo valor son objetos diferentes, mientras que un objeto puede tener valores diferentes en momentos diferentes, pero siempre es el mismo objeto. Al igual que los objetos, las tablas tienen un ciclo de vida que es independiente de quién las creó o dónde se crearon.

Crear una clase simple

A continuación se muestra una implementación de clase simple para un rectángulo con tres propiedades de área, longitud y amplitud. También tiene una función printArea para imprimir el área calculada.

- Super clase
Rectangle = {area = 0, length = 0, breadth = 0}

function Rectangle:new (o,length,breadth)
   o = o or {}
   setmetatable(o, self)
   self.__index = self
   self.length = length or 0
   self.breadth = breadth or 0
   self.area = length*breadth;
   return o
end

function Rectangle:printArea ()
   print("The area of Rectangle is ",self.area)
end

Crear un objeto

Crear un objeto es el proceso de asignación de memoria para la instancia de clase. Cada uno de los objetos tiene su propia memoria y comparte los datos de la clase común.

r = Rectangle:new(nil,10,20)
print(r.length) 	--r.atributo para acceder al estado del objeto
r:printArea() 		-- para enviarle un mensaje al objeto
Ejemplo completo:
-- Meta class
Shape = {area = 0}

-- Base class method new

function Shape:new (o,side)
   o = o or {}
   setmetatable(o, self)
   self.__index = self
   side = side or 0
   self.area = side*side;
   return o
end

-- Base class method printArea

function Shape:printArea ()
   print("The area is ",self.area)
end

-- Creating an object
myshape = Shape:new(nil,10)

myshape:printArea()
Herencia en Lua:

Veamos una simple extensión de clase. Tenemos una clase como se muestra a continuación.

-- Meta class
Shape = {area = 0}

-- Base class method new

function Shape:new (o,side)
   o = o or {}
   setmetatable(o, self)
   self.__index = self
   side = side or 0
   self.area = side*side;
   return o
end

-- Base class method printArea

function Shape:printArea ()
   print("The area is ",self.area)
end

Podemos extender la forma a una clase cuadrado como se muestra a continuación.

Square = Shape:new()

-- Derived class method new

function Square:new (o,side)
   o = o or Shape:new(o,side)
   setmetatable(o, self)
   self.__index = self
   return o
end

Funciones básicas de override:

Podemos anular las funciones de la clase base que, en lugar de usar la función en la clase base, la clase derivada puede tener su propia implementación como se muestra a continuación:

-- Derived class method printArea

function Square:printArea ()
   print("The area of square is ",self.area)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment