Inicio   Discusión   Ayuda e introducción   Módulos disponibles   Zona de pruebas  


Gran parte de esta página está basada en la presentación en PDF de Tim Starling del hackathon 2012 de Berlín

Bienvenidos a la introducción de Lua con Scribunto, la página de ayuda para los principiantes para aprender a hacer scripts Lua en MediaWiki, y un resumen para programadores más avanzados.

El contenido está destinado principalmente a los desarrolladores familiarizados con las plantillas de MediaWiki. Si eres un experto en plantillas MediaWiki, pero recién llegado a Lua, aprenderáss algunas nuevas instrucciones mágicas. Si tiene experiencia con Lua pero no con plantillas, puede encontrar más información en Ayuda: Plantilla. Tenga en cuenta que algunas cosas de Scribunto no se aplican en la distribución Lua. Si no sabe ni lo uno ni lo otro, encontrará que en la comunidad de Wikipedia hay gente dispuesta a ayudarle.

Introducción para nuevos programadores

editar

Hola mundo

editar

El primer ejercicio típico es saber escribir Hola mundo con el nuevo lenguaje. Cree una página en el espacio de nombres Module. El formato recomendado para pruebas es: Module:Zona de pruebas/nombre de usuario/nombre del módulo. A continuación se explica en detalle el formato de Módulo:Demo:


local p = {}    -- Todos los módulos en Wikipedia comienzan definiendo una variable 
                -- que tendrá todas las funciones accesibles externamente 
                -- Estas variables pueden tener el nombre que desee 
function p.hola(frame)  -- Añadir una función al objeto "p" 
                        -- Estas funciones se podrán invocar en otras páginas vía #invoke 
                        -- "frame" contiene los datos que Wikipedia envía a esta función 
    return '¡Hola mundo!' -- Sale de la función con la información a devolver a la Wikipedia 
end          -- Final de la función "hola" 
 
return p     -- Todos los módulos terminan retornando a la Wikipedia la variable 
             -- que contiene las funciones

Puede ejecutar en una página wiki, por ejemplo en la misma página de discusión de pruebas:

{{#invoke:mi_módulo|hola}}

Esto invoca el módulo mi_módulo, o como lo haya llamado, y la función exportada "hola" de este módulo. Sustituye la invocación por el texto devuelto por la función. Normalmente las invocaciones se harán desde una plantilla.

Estructuras de control

editar
si ... entonces... si ... entonces... si no ... si ... entonces... o si ... si no ...
if color == 'negro' then
    cssColor = '#000'
end
if color == 'negro' then
    cssColor = '#000'
else
    cssColor = color
end
if color == 'negro' then
    cssColor = '#000'
elseif color == 'blanco' then
    cssColor = '#fff'
else
    cssColor = color
end

Los dos signos == comprueban la igualdad. Un solo signo = es para asignar.

Bucle for:

f = 1 -- asigna el valor inicial
for i = 1, 5 do
    f = f * i
end
return 'El factorial de 5 es ' .. f

Los dos guiones - son para añadir comentarios. Los dos puntos seguidos .. son para concatenar.

Tipos de datos

editar
  • Cadena (string), entre comillas simples ('...') o dobles ("..."). Cuidado con los apóstrofos rectos.
  • Numérico, con punto decimal.
  • Booledana: "true" o "false" (verdadero o falso)
  • "Nil" (nulo)
  • Tabla
  • "Function" (función)

Operadores lógicos

editar
and: Los dos son verdaderos or: Uno, el otro o ambos not: Lo que sigue es falso
if tostada and mantequilla then
    return 'desayuno'
end
if pechuga or muslo then
    return 'almuerzo'
end
if not hambre then
    return 'ayunar'
end

Funciones

editar

Declaración de funciones:

sin argumentos con argumentos función no local para llamar fuera del módulo
local function getColour()
    return 'azul'
end
local function plural(mundo)
    return mundo .. 's'
end
local p = {}
function p.hola()
    return '¡Hola mundo!'
end
return p

Para llamar a la función:

colour = getColour()
colorPlural = plural('azul')

Variables

editar

Hay tres tipos de variables: variables globales, variables locales y tablas. Una variable se considera global a no ser que se declare explícitamente con la clave local. Una variable local es visible dentro del bloque donde ha sido declarada. Una variable declarada sin asignación tiene valor nil (nulo).


x = 10           -- variable global
do               -- nuevo bloque
    local x = x  -- nueva x asignada el valor de la anterior
    x = x + 1    -- 11
end              -- cierra el bloque y sus variables locales
return x         -- 10, la global
local x
if ready then
    x = 've allí'
end
-- x es 've allí' si
-- ready, si no nil (nulo)

Creación de una tabla:

números = {uno = 1, dos = 2, tres = 3}

Acceso a un elemento de la tabla:

return números.dos    -- devuelve 2
return números['dos'] -- también devuelve 2

Tabla numerada:

africanFlatbreads = {
    'Aish Mehahra',
    'Injera',
    'Lahoh',
    'Ngome'
}
return africanFlatbreads[2] -- devuelve 'Injera'

Iteración de elementos de la tabla:

pairs: par clave/valor en orden aleatorio ipairs: claves numéricas en orden ascendente
for nombre, número in pairs(números) do
    ...
end
for index, bread in ipairs(africanFlatbreads) do
    ...
end

Cadenas

editar
#, longitud sub, substring
s = 'hola'
return #s  -- devuelve 4
s = 'hola'
return s:sub(2,3)  -- devuelve 'ol'
return s:sub(2)    -- devuelve 'ola'
return s:sub(-2)   -- devuelve 'la'

Introducción para los programadores

editar

Léxico

editar
  • El formato de comentarios recuerda SQL
    -- comentario en una única línea
    --[[
    comentario largo
    --]]
  • Los saltos de línea son ignorados.
  • Los puntos y comas para terminar las declaraciones son opcionales y no son recomendados.

Tipos de datos

editar
  • Nil (nulo)
  • Numèricos, un único formato de punto flotante de precisión doble.
  • Strings (cadenas), 8-bit
  • Booledanos
  • Funciones
    • Valores de primera clase.
    • Devuelve valores múltiples.
    • Los valores de retorno múltiples no están ligados a un tipo de dato.
    • Sintaxis anónima
x = function()
    ...
end
  • Tablas
    • Implementadas como hashtable
    • Usadas para OOP, com Javascript
    • Sintaxis literal: {nombre = valor} o {a, b, c}
    • Acceso con foo.bar o foo['bar']

Operadores

editar
  • No igual: ~= (en lugar de !=)
  • Concatenación: ..
  • Longitud: #
  • Lógicos: and, or, not
  • Exponencial: ^
  • Con el significado habitual: <, >, <=, >=, ==, +, -, *, /, %
  • Operadores omitidos:
  • Asignación. Como en BASIC, la asignación es una declaración completa, no una expresión.
Asignación múltiple Asignación con declaración de variable local
a, b = c, d
a, b = foo()
local a, b = c, d
local a = b, c = d -- así no!

Estructuras de control

editar
  • Bloque explícito
do
    ...
end
  • Bucles
Bucle con condición inicial Bucle con condición final
while cond do
    ...
end
repeat
    ...
until cond
For numèrico For genèrico
for i = start, stop do
    ...
end
for i in iterator
    ...
end
La variable de índice es local del bucle
  • If
if cond then
    ...
elseif cond then
    ...
else
    ...
end
  • Variables
    • Ámbito léxico, casi idéntico a JavaScript.
    • Una variable no determinada es idéntica a una variable nil.
    • Ninguna sintaxis especial para suprimir, simplemente x = nil.
    • El acceso a variables no definidas no genera errores.
  • Objetos
    • Hechos de tablas utilizando una variedad de sintaxis, similar a JavaScript.
    • Variables de elementos privados implementadas con ámbito léxico, como en JavaScript.
    • Punto para métodos estáticos: obj.func ()
    • Dos puntos para métodos no estáticos: obj: func ()
    • Ejemplo de estilo de construcción de una función:
function newObj()
    local private = 1
    local obj = {}
    function obj:getPrivate()
        return private
    end
    return obj
end

Interfaz de MediaWiki

editar

Todo el código Lua está en el espacio de nombres Módulo. Hay disponible un editor de código Ace.

Invocación:

{{ #invoke: nombre_módulo | nombre_función | arg1 | arg2 | nombre1 = valor1 }}

Las instancias de invocación son aisladas, los globales definidos en una no están disponibles en otra.

Un módulo es un bloque Lua que devuelve una tabla de exportación. Se proporciona require () y librería package. La función de exportación devuelve una cadena de texto wiki, convirtiendo los valores que no son string. Los valores múltiples de retorno son concatenados.

Métodos frame:

  • args:
local nombre1 = frame.args.nombre1
  • argumentPairs():
local t = {}
for nombre, valor in frame:argumentPairs() do
    t[name] = value
end
  • getParent(): Proporciona acceso al frame superior, por ejemplo los argumentos de la plantilla que llamó #invoke
  • Preproceso de texto wiki
frame:preprocess('{{plantilla}}')
  • Invocación estructurada de plantilla
frame:expandTemplate{
    title = 'plantilla',
    args = {foo = foo}}
Los argumentos son siempre expandidos. No es necesario construir preprocesar las entradas de los argumentos.

Posibilidades en el futuro:

  • Invocación interwiki de módulos.
  • Otros lenguajes diferentes a Lua.
  • Funciones de fecha y hora.
  • Acceso directo a funciones parser y variables como {{PAGENAME}}, {{#ifexists:}}.

Depuración de los módulos

editar

Cuando el resultado no es lo que esperábamos de un módulo que hemos creado o retocado, y no acabamos de encontrar el error al repasar el código, entonces querremos ver los valores que toman algunas variables o el flujo del programa (señalando con unas etiquetas las líneas por donde debería seguir el flujo). Este proceso de revisión y corrección es lo que se denomina depuración. Aquí mencionaremos como se puede revisar el código.

Revisión simple

editar

Cuando queremos ver el valor de una variable en un solo punto del módulo:

Modificando el código

editar

Podemos utilizar la función (para cualquier punto del módulo) error(). Así si queremos saber el valor de var, añadiremos una línea en el módulo con error(var).

Pero en el caso de que sea una tabla (tab, en lo que sigue) tendremos que utilizar mw.dumpObject(tab) o, si no tiene tablas anidadas, también se puede utilizar table.concat(tab,', ') como parámetro de la función error.

Sin modificar el código

editar

Para obtener variables y los valores devueltos por funciones (no locales en ambos casos) podemos utilizar la "consola de depuración de errores" que aparece debajo de todo de la página del módulo (cuando se lo está editando). Para ello utilizaremos mw.log y mw.logObject. Veamos su utilidad en un ejemplo descrito a continuación (módulo que se puede encontrar aquí):

local p = {}
p.Hola = 'Hola'
function p.calcula(num)
   return num
end
function p.sum_mult(num)
   return num + num, num * num
end
function p.mtable(num)
   return {num, num+1}
end
return p

Peticiones en la "consola de depuración de errores":

Petición Valor devuelto
mw.log(p.Hola) "Hola"
mw.log(p.calcula(10/2) 5
mw.log(p.sum_mult(3))) 6   9
mw.log(p.mtable(4)) table
mw.logObject(p.mtable(4))

table#1 {

4,
5,

}

La consola de edición no guarda las peticiones y se tienen que copiar o reescribir de nuevo en cada modificación del módulo.

Revisión del flujo y de los valores de las variables en diversos puntos

editar

Las funciones del Módulo:SimpleDebug se utilizan para casos como los anteriormente citados o para casos más complejos:

  • Cuando una variable o el valor (o valores) devueltos por una función sean locales.
  • Cuando interese los valores que toma una variable (o varias) en varios puntos (incluidos en módulos requeridos).
  • Para ver si el flujo del programa pasa por un punto (al que etiqueta).
  • Para limitar el número de valores devueltos dentro de un bucle o establecer condiciones para que sea efectivo el registro de dichos valores.

Para saber más

editar