Viquipèdia:Lua/Introducció

De Viquipèdia
Salta a la navegació Salta a la cerca
Gran part d'aquesta pàgina està basada en la presentació en PDF de Tim Starling al Hackathon 2012 de Berlín.

Benvinguts a la introducció de Lua amb Scribunto, la pàgina d'ajuda per a novells per aprendre a fer scripts Lua a MediaWiki, i un resum per a programadors més avançats.

El contingut està destinat principalment als desenvolupadors familiaritzats amb les plantilles de MediaWiki. Si sou un expert en plantilles MediaWiki, però nouvingut a Lua, aprendreu algunes noves instruccions màgiques. Si teniu experiència amb Lua però no amb plantilles, podeu trobar més informació a Ajuda:Plantilla. Tingueu en compte que algunes coses de Scribunto no s'apliquen en la distribució Lua. Si no sabeu ni una cosa ni l'altre, trobareu que a la comunitat de la Viquipèdia hi ha gent disposada a ajudar-vos.

Introducció per a nous programadors[modifica]

Hola món[modifica]

El primer exercici típic és saber escriure Hola món amb el nou llenguatge. Creeu una pàgina en l'espai de noms Module. El format recomanat per a proves és: Module:Proves/Nom d'usuari. A continuació s'explica en detall el format de Mòdul:Demo:

local p = {}     -- Tots els mòduls a la Viquipèdia comencen definint una variable
                 -- que tindrà totes les funcions accessibles externament
                 -- S'usa "p" de package (empaquetatge) però pot tenir el nom que vulgueu
function p.hola(frame)   -- Afegeix una funció a l'objecte "p"
                         -- Aquestes funcions es podran invocar en altres pàgines via #invoke
                         -- "frame" conté les dades que la Viquipèdia envia a aquesta funció
    return 'Hola, món!'  -- Surt de la funció amb la informació a retornar a la Viquipèdia
end         -- Final de la funció "hola"

return p    -- Tots els mòduls acaben retornant a la Viquipèdia la variable 
            -- que conté les funcions

Podeu executar-lo en una pàgina wiki, per exemple en la mateixa pàgina de discussió de proves:

{{#invoke: my_module | hola }}

Això invoca el mòdul my_module, o com l'hagueu anomenat, i la funció exportada "hola" d'aquest mòdul. Substitueix la invocació pel text retornat per la funció. Típicament les invocacions es faran des d'una plantilla.

Estructures de control[modifica]

Vegeu estructures de control
si ... llavors ... si ... llavors ... si no ... si ... llavors ... o si ... si no ...
if color == 'negre' then
    cssColor = '#000'
end
if color == 'negre' then
    cssColor = '#000'
else
    cssColor = color
end
if color == 'negre' then
    cssColor = '#000'
elseif color == 'blanc' then
    cssColor = '#fff'
else
    cssColor = color
end

Els dos signes == comproven la igualtat. Un sol signe = és per assignar.

Bucle For:

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

Els dos guionets -- són per afegir comentaris. Els dos punts seguits .. són per concatenar.

Tipus de dades[modifica]

  • Cadena (string), entre cometes simples ('...') o dobles ("..."). Atenció amb els apòstrofs rectes.
  • Numèric, amb punt decimal.
  • Booleà: "true" o "false" (verdader o fals)
  • "Nil" (nul)
  • Taula
  • "Function" (funció)

Operadors lògics[modifica]

and: els dos són verdaders or: un o l'altre o tots dos not: el que segueix és fals
if torrades and mantega then
    return 'esmorçar'
end
if pit or cuixa then
    return 'dinar'
end
if not gana then
    return 'dejú'
end

Funcions[modifica]

Declaració de funcions:

sense arguments amb arguments funció no local per cridar fora del mòdul
local function getColour()
    return 'blau'
end
local function plural(word)
    return word .. 's'
end
local p = {}
function p.hola()
    return 'Hola, món!'
end
return p

Per cridar la funció:

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

Variables[modifica]

Hi ha tres tipus de variables: variables globals, variables locals i taules. Una variable es considera global a no ser que es declari explícitament amb la clau local. Una variable local és visible dins del bloc on ha estat declarada. Una variable declarada sense assignació té el valor nil.

x = 10           -- variable global
do               -- nou bloc
    local x = x  -- nova x assignant el valor de l'anterior
    x = x + 1    -- 11
end              -- tanca el bloc i les seves variables locals
return x         -- 10, la global
local x
if ready then
    x = 'vés-hi'
end
-- x és 'vés-hi' si
-- ready si no nil

Creació d'una taula:

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

Accés a un element de la taula:

return números.dos    -- retorna 2
return números['dos'] -- també retorna 2

Taula numerada:

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

Iteració dels elements de la taula:

pairs: parell clau/valor en ordre aleatori ipairs: claus numèriques en ordre ascendent
for nom, número in pairs(números) do
    ...
end
for index, bread in ipairs(africanFlatbreads) do
    ...
end

Cadenes[modifica]

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

Introducció per a programadors[modifica]

Lèxic[modifica]

  • El format de comentaris recorda SQL
    -- comentari en una única línia
    --[[
    comentari llarg
    --]]
  • Els salts de línia són ignorats
  • Els punts i comes per acabar les declaracions són opcionals i no recomanats

Tipus de dades[modifica]

  • Nil
  • Numèrics, un únic format de punt flotant de precisió doble
  • Strings, 8-bit
  • Booleà
  • Funcions
    • Valors de primera classe
    • Retorna valors múltiples
    • Valors de retorn múltiples no estan lligats a un tipus de dada
    • Sintaxi anònima
x = function()
    ...
end
  • Taules
    • Implementades com a hashtable
    • Usades per OOP, com Javascript
    • Sintaxi literal: {nom = valor} o {a, b, c}
    • Accés amb foo.bar o foo['bar']

Operadors[modifica]

  • No igual: ~= en lloc de !=
  • Concatenació: ..
  • Longitud: #
  • Lògics: and, or, not
  • Exponencial: ^
  • Amb el significat habitual: <, >, <=, >=, ==, +, -, *, /, %
  • Operadors omesos:
    • Cap operador d'assignació com +=. Un sol igual = no és realment un operador.
    • Cap operador bit a bit
    • Cap operador ternari ?:
  • Assignació. Com a BASIC, l'assignació és una declaració completa, no una expressió
Assignació múltiple Assignació amb declaració de variable local
a, b = c, d
a, b = foo()
local a, b = c, d
local a = b, c = d -- no així!

Estructures de control[modifica]

  • Bloc explícit
do
    ...
end
  • Bucles
Bucle amb condició inicial Bucle amb condició final
while cond do
    ...
end
repeat
    ...
until cond
For numèric For genèric
for i = start, stop do
    ...
end
for i in iterator
    ...
end
La variable d'índex és local del bucle
  • If
if cond then
    ...
elseif cond then
    ...
else
    ...
end

Dades[modifica]

  • Variables
    • Àmbit lèxic, gairebé idèntic a JavaScript
    • Una variable no determinada és idèntica a una variable nil
      • Cap sintaxi especial per suprimir, simplement x = nil
      • Cap error alçat en accedir a una variable no definida
  • Objectes
    • Fets de taules utilitzant una varietat de sintaxis, similar a JavaScript
    • Variables d'elements privats implementades amb àmbit lèxic, com en JavaScript
    • Punt per a mètodes estàtics: obj.func()
    • Dos punts per a mètodes no estàtics: obj:func()
    • Exemple d'estil de construcció d'una funció:
function newObj()
    local private = 1
    local obj = {}
    function obj:getPrivate()
        return private
    end
    return obj
end

Interfície a MediaWiki[modifica]

Tot el codi Lua és en l'espai de noms Module. Hi ha disponible un editor de codi Ace.

Invocació[modifica]

{{ #invoke: nom_mòdul | nom_funció | arg1 | arg2 | nom1 = valor1 }}

Les instàncies d'invocació són aïllades, els globals definits en una no estan disponibles en una altra.

Un mòdul és un bloc Lua que retorna una taula d'exportació. Es proporciona require() i llibreria package. La funció d'exportació retorna una cadena de text wiki, convertint els valors que no siguin string. Els valors múltiples de retorn són concatenats.

Mètodes frame[modifica]

  • args:
local nom1 = frame.args.nom1
  • argumentPairs():
local t = {}
for nom, valor in frame:argumentPairs() do
    t[name] = value
end
  • getParent(): Proporciona accés al frame superior, per exemple els arguments de la plantilla que va cridar #invoke
  • Preprocés de text wiki
frame:preprocess('{{plantilla}}')
  • Invocació estructurada de plantilla:
  • En cas d'un sol paràmetre posicional:
frame:expandTemplate{
    title = 'plantilla',
    args = {foo}}
  • En cas d'un paràmetre nominatiu (en l'exemple "param"):
frame:expandTemplate{
    title = 'plantilla',
    args = {param = foo}}
Els arguments són sempre expandits. No cal construir preprocessar les entrades dels arguments.

Possibilitats de futur[modifica]

  • Invocació interwiki de mòduls
  • Altres llenguatges diferents a Lua
  • Funcions de data i hora
  • Accés directe a funcions parser i variables com {{PAGENAME}}, {{#ifexists:}}

Depuració dels mòduls[modifica]

Quan el resultat no és el que esperàvem d'un mòdul que hem creat o retocat, i no acabem de trobar l'error en repassar el codi, llavors caldrà poder veure els valors que prenen algunes variables o el flux del programa (senyalant amb unes etiquetes les línies per on hauria de seguir el flux). Aquest procés de revisió i correcció és el que s'anomena depuració. Aquí esmentarem com es pot revisar el codi.

Revisió simple[modifica]

Quan volem veure el valor d'una variable en un sol punt del mòdul:

Modificant el codi

Podem utilitzar la funció (per a qualsevol punt del mòdul) error(). Així si volem saber el valor de var, afegirem una línia en el mòdul amb error(var).

Però en el cas que sigui una taula (tab, en el que segueix) haurem d'utilitzar mw.dumpObject(tab) o, si no té taules niuades, també es pot utilitzar table.concat (tab,',') com a paràmetre de la funció error().

Sense modificar el codi

Per obtenir variables i els valors retornats per funcions (no locals en els dos casos) podem utilitzar la "Consola de depuració" que apareix a baix de tot de la pàgina del mòdul (quan aquest està en mode d'edició). Per a això utilitzarem mw.log i mw.logObject. Vegem la seva utilitat en un exemple descrit a continuació (mòdul que podem trobar 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

Peticions a "Consola de depuració":

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

table#1 {

8,
9,

}

La consola de depuració no desa les peticions i s'han de copiar o reescriure de nou en cada modificació del mòdul.

Revisió del flux i dels valors de les variables en diversos punts[modifica]

Les funcions del Mòdul: SimpleDebug s'utilitzen per a casos com els anteriorment citats o per a casos més complexos:

  • Quan una variable o el valor (o valors) retornats per una funció siguin locals.
  • Quan interessi els valors que pren una variable (o diverses) en diversos punts (inclosos en mòduls requerits).
  • Per veure si el flux del programa passa per un punt (al qual etiquetareu).
  • Per limitar el nombre de valors retornats des d'un bucle o establir condicions perquè sigui efectiu el registre de valors.

Per saber-ne més[modifica]