Helpo:Lua/Modulo en Vikio

Logo de la Lua-lingvo Lua

VP:LUA

Kategorioj
Ŝablonoj
  • {{LuaModuleDoc}} por la dokumentado de modulo, por aranĝi la keston kun ligiloj
  • {{Modula statuso}} por la dokumentadoj de modulo, por indiki la evoluan statuson de modulo
  • {{Kun Lua-modulo}} por la dokumentado de ŝablono, kiu uzas Lua-modulon aŭ eĉ entute baziĝas sur modulo
  • {{Uzanto Projekto/Lua}} por uzantopaĝoj
Vidu ankaŭ
Komentoj
  1. (per {{Kun Lua-modulo}})
  2. (per {{LuaModuleDoc}})
vdr

Ĉi tiu helpopaĝo priskribas por Lua-programistoj la efikon de Lua-modulo en la kunteksto de Vikiaj paĝoj.

Fontoteksto kaj paĝoj redakti

  • Ĉiuj paĝoj en la nomspaco Modulo: (828) estas principe la fontokodo ĉiufoje por ununura Lua-modulo. Tio ne estas interpretata kiel Vikia teksto. La enhava modelo (angle Content Model) estas Scribunto.
  • Nur paĝoj, kies nomo sekvas la skemon por komentoj, en la esperanta Vikipedio finiĝantaj do per /dokumentado, povas enhavi Vikian tekston.
  • Krome estas la eblo, efikigi en certaj subpaĝoj de la uzanto-provejo en la kadro de la ŝablona provejo Lua-Modulojn.
  • Paĝoj de aliaj nomspacoj ne povas esti uzataj per #invoke tial, ĉar la nomspaco estas antaŭmetata al ĉi tiu instrukcio interne. Ankaŭ require() estas nur ebla sur paĝoj, kies enhavo estas konservata kiel Lua-fontokodo („Content Model“).
  • Ceteraj subpaĝoj en la nomspaco Modulo: enhavu nur ne-memstaran Lua-kodon
    • Neniu ŝablono aŭ alia modulo uzu tiajn paĝojn; escepte per mw.loadData() uzataj datumaroj.
    • Ordinare ĝi estas el la memstara modulo eligita kodo, por kio povas esti diversaj bonaj kialoj.
    • Ĝi povus esti ankaŭ sub la nomo /testo eligita unit test.
    • Ĝi povus esti ankaŭ sub la nomo /provejo eligita modula provejo.

Enkapsuligo redakti

La modulo estas konscie tiel aranĝata, ke ne eblas iu ajn aliro de unu enplekto per #invoke al alia aŭ la enhavo de la ĉirkaŭanta paĝo. Kelkaj trukaj provoj, subfosi tion, jam post mallonga tempo estis malebligataj.[1]

Modulo mem ne povas kaŭzi iun ajn ŝanĝon je la mondo (escepte de tio, ke ĉe la „Ligiloj ĉi tien“ povas aldoniĝi enskribo per enplektado de aliaj paĝoj; aŭ ke ĝi pliplenigas la Kategorion de la paĝoj kun skripteraroj). Ĝi povas esprimi sin eksklude per sia redona valoro, kiu finfine devus efiki en ajna maniero al ŝablona enplekto.

La modulo povas ellegi la parametrojn de la ŝablona enplekto (aŭ de cetera paĝo, en kiu la #invoke aperas). Al ĝi estas krome konate, kiel la entuta paĝo nomiĝas, kiu estas prezentata al la uzanto. Pli multe la modulo ne povas eltrovi pri sia ĉirkaŭaĵo (gepatra ĉirkaŭaĵo). Kiel la ŝablono nomiĝas, en kiu #invoke staras, ne povas esti eltrovata.

La malloka variablo _G redakti

_G estas table, kiu norme enhavas la poste listigatajn komponaĵojn:

_G _VERSION assert debug error getmetatable ipairs math mw next os package pairs pcall rawequal rawget rawset require select setmetatable string table tonumber tostring trim type unpack xpcall

En manlibro sur Mediawiki legeblas:

Note that every required module is loaded in its own sandboxed environment, so it cannot export global variables as is sometimes done in Lua 5.1. Instead, everything that the module wishes to export should be included in the table returned by the module.

Fakte tamen en majo 2013 en _G estas kolektataj el ĉiuj per require() enplektitaj moduloj tiuj variabloj, kiuj tie ne estis deklaritaj kiel local. Sed estas tre verŝajne, ke tio ne plu longe estos la kazo; pli bone estas orda redono laŭ eksporto-table.

Redona valoro de la modulo redakti

La lasta linio de modulo devas esti return-instrukcio kun unu redona valoro. Se tio mankus, la valoro ĉiam estus nil.

La datumtipo de ĉi tiu redona valoro estas principe ajna. Disvastiĝinta estus table, sed ankaŭ function estus imagebla; finfine ankaŭ neeviteble apenaŭ variebla signoĉeno aŭ numero.

La redona valoro devas estas analizata en tri kazoj :

  1. Kiel valoro de la alvoko de require().
  2. Kiel valoro de mw.loadData().
  3. Se ĝi estas table, ĝi igas por #invoke la disponeblajn funkciojn alireblaj.

Interfaco al la ŝablona programado redakti

En la enplektantan paĝon estas enigata per la malkomponila funkcio {{#invoke:M|fun|params}}.

fun estas la nomo de funkcio, kiu estas komponaĵo en la kiel table deklarita redona valoro de la modulo M. Ĝi ricevas kiel parametron la objekton frame de #invoke.

La parametra listo respondas al tiu ĉe ŝablonoj. Devojiĝintaj egalosignoj en la valoro de nenomita parametro povas kaŭzi sintaksan eraron. Ĉe venantaj de ekstere valoroj ĉiam okazu per antaŭmetata kontinua numero certa asigno: |1={{{teksto|}}}

Analizo en la funkcio redakti

En la funkcio estas disponebla la parametra listo en objekto frame kiel table frame.args.

Male al ŝablonoj ankaŭ malplena asigno |x= | estas analizebla; tio estas: Povas esti eltrovata, ke x en la parametra listo estas nomata, sed la malplena valoro estis asignita.

La valoro de komponaĵo de frame.args estas string, se la parametro ekzistas en #invoke, kaj alie nil.

Kiel ankaŭ ĉe ŝablonoj validas: nomataj parametroj estas tondretaj (interspacaj signoj kaj linisaltoj antaŭ kaj post la valoro estas forigataj); nenomitaj parametroj ne.

Kiel ekzemplon rigardu la Modulo:Saluton.


La ordigo en grupojn estas legebla plej bone el la sekva ekzemplo por modulo M kun la funkcio f:

{{#invoke:M|f|1=ABC|FGH| LMN |nomataA=PQR|nomataB=  TUV | ALTO SUPER NN= 32 | Malplenaj pakumoj= }}

redonas

frame.args[ 1 ] »ABC«
frame.args[ 2 ] »FGH«
frame.args[ 3 ] » LMN «
frame.args.nomataA »PQR«
frame.args.nomataB »TUV«
frame.args[ "ALTO SUPER NN" ] »32«
frame.args.Malplenaj pakumoj »«
frame.args.Nenomita nil

Redona valoro de funkcio por ŝablonoj redakti

La redona valoro de nomita en #invoke funkcio anstataŭigas kiel signoĉenon la aron {{#invoke:}}.

Kiel redona valoro oni ĉiam kreu eksplicite signoĉenon. Se la redona valoro estas de alia tipo, tio estas konvertata per normaj operacioj en signoĉenon. Per tio povas esti legebla en la paĝo la vorto falsenil aŭ la programado kondukas al malĝustaj konkludoj. La lasta estas evitebla per esprimo:

return r or ""

Se r estas „io“, r estas redonata, alie "".

Pluraj redonaj valoroj aŭ agregita datumtipo estus transformataj por #invoke aŭtomate per uzado de la funkcio tostring() en signoĉenojn kaj tiam estus sen disigaj signoj ligataj unu al alia. Tio estu evitata kaj estu perkode kreata signoĉeno, kiu tiam ankaŭ taŭgus por la artikolo.

Objekto frame redakti

Scribunto-Dokumentado (angle)

La objekto frame redonas la ĉirkaŭaĵon. Principe ekzistas du instancoj:

  1. Alvoko de #invoke (Norma kazo; laŭnorme ĉiam nomata per frame)
  2. Alvoko de la enplektanta paĝo (plej ofte ŝablono).
    • Ricevebla per frame:getParent()
    • La ununura uzebla diferenco estas la argumentoj frame.args de la ŝablona enplektado; ĉiuj funkcioj kondukas al la sama rezulto; denova frame:getParent() ne helpas.

Se per #invoke funkcio por la ŝablono estas uzata, al la funkcio laŭ Interfaco al la ŝablona programado ankaŭ estas konata la objekto frame. Se tio (kiel biblioteka funkcio) ne estis transdonita aŭ ne estis tradonita en pli profundajn ebenojn, ĝi povas esti formata ĉie per:

frame = mw.getCurrentFrame()

Komponaĵoj redakti

Rekte uzeblaj estas:

frame.args
Donitaj parametroj kiel table.
  • Principe parametroj de #invoke – laŭ frame:getParent() Ŝablonaj parametroj de la enplektanta paĝo.
frame:callParserFunction()
Ekzekuto de malkomponila funkcio.
r = frame:callParserFunction( name, args )
Diversaj formoj estas eblaj por la argumenta listo.
La argumentoj estas transdonataj neprilaboritaj al la malkomponila funkcio.
Kie tio eblas, estu preferataj Lua-internaj funkcioj.
frame:expandTemplate()
Enplektado de alia paĝo.
r = frame:expandTemplate{ title = s, args = args }
Estas nur ebla ĉi tiu datumaranĝo kun nomataj parametroj kaj kunigaj krampoj.
frame:extensionTag()
Analoge al frame:callParserFunction() kun ĉirkaŭata de etikedoj enhavo.
r = frame:extensionTag( name, content, args )
Diversaj formoj estas eblaj por la argumenta listo.
frame:getParent()
Objekto frame por la enplektanta paĝo (gepatra ĉirkaŭaĵo).
frameT = frame:getParent()
frame:preprocess()
Ekspansias kompleksan Vikian tekston.
Ŝablonoj, malkomponilaj funkcioj kaj parametroj kiel {{{1}}} estas analizataj.
Unuopa ŝablono estu ekspansiata anstataŭ tio per frame:expandTemplate().
frame:preprocess( string )

Pluraj moduloj redakti

Enplektado redakti

La funkcio require() enplektas alian modulon.

  • Parametro estas signoĉeno kun la nomo de la modulo.
    • La nomspaco Modulo: estas antaŭmetenda.
  • Rezultas sekvaj valoroj:
    1. tablestring, se tio estis redona valoro.
    2. true se la paĝonomo alie ekzistas kaj kiel Lua-fontokodo estas administrata.
    3. Skripteraro kaj interrompo, se la paĝonomo ne ekzistas aŭ la enhavo ne validas kiel Lua-fontokodo aŭ ĝenerala sintakseraro aperas en la paĝo (neniu valida enhavo content).

Ekzemplo por sekura enplekto:

local lucky, VolasHavi = pcall( require, "Modulo:VolasHavi" )
if type( VolasHavi ) == "table" then
    r = VolasHavi.VolasHavi()
else
    r = "<span class='error'>" .. VolasHavi .. "</span>"
    --  auto: "package.lua:80: module `Modulo:VolasHavi' not found"
    --  "Eraro * Modulo:VolasHavi ne trovita"
end

pcall() estas kraŝosekura; la dua redona valoro estas en sukcesa kazo la redona valoro de la modulo, alie la erarmesaĝo de require().

mw.loadData() redakti

Ĉi tiu funkcio respondas principe al require() kun du apartaĵoj:

  • La elementoj de la redona valoro povas enhavi nur bazajn datumtipojn (antaŭ ĉio signoĉenojn kaj numerojn); sed ne funkciojn.
  • La okazinta enplekto estas notata, tiel ke plurfoja #invoke ene de tuta paĝo estas akcelata.

Tio estas planata por grandaj datumaroj, kiuj tiam ankaŭ aparte de la funkcioj povas esti flegataj en la modulo.

Eksporto por aliaj moduloj redakti

La norma tasko estas, subteni ŝablonon per #invoke. Koncepte estas la eblo, aldone aŭ eksklude subteni aliajn Lua-modulojn per require(). Ĉe tio estas du kazoj:

  1. Kaj ŝablonoj kaj moduloj estas subtenataj per laŭbezone adaptitaj funkcioj de la sama celo.
    • Proponas sin, oferti la funkciojn kun la sama nomo en ambaŭ alirmanieroj.
      • La genera funkcio tiam estas la versio por la Lua-alvoko.
      • La varianto por la ŝablona programado transskribas ankoraŭ nur la enigajn parametojn, elvokas la generan funkcion kaj certigas la taŭgan rezulton por la ŝablonoj.
      • Ĉe la ŝablona programado eblas eksklude signoĉenoj kiel parametroj, dum ke la genera funkcio ankaŭ permesas aliajn tipojn kiel ekzemple numerajn valorojn aŭ table. Ĉe #invoke transdonataj parametraj valoroj devas esti konvene interpretataj (malkomponi).
    • Ekzemplo: vidu malsupre
  2. Estas eksklude ofertataj funkcioj por Lua-moduloj; la taskoj ne taŭgas por ŝablonoj.

Eksportitaj funkcioj estas aplikataj kune kun la table de sia difinanta modulo. Tio nomiĝas ĉiam tiel kiel la modulo mem. Ĉar la nomoj de la moduloj en la nomspaco estas unusignifaj, ne povas okazi nomaj konfliktoj. Per tio tuj klaras, de kie devenas funkcio kaj kie la dokumentado estas trovebla, se subite estas trovata en la fontoteksto nekonata funkcia alvoko.

Simpla modulo por ŝablonoj redakti

La Modulo:Saluton donas unuan enigon:

  local p = {} 
  function p.hello(frame)
      local name = frame.args[1]
      if not name then name = 'mondo' end
      return  'Saluton, ' .. name .. '! Tio estas Lua!' 
  end 
  return p

Strukturado de pli kompleksaj moduloj redakti

Modulo kun du aŭ tri funkcioj nur por ŝablonoj estas eĉ sufiĉe triviala.

Ĉe pli kompleksaj taskoj necesas iom da strukturado kaj superrigardo.

  • Je la komenco ankaŭ dato estu notata.
    • Ĉar versioj de la fontokodo ne eksklude estas generataj per la produktiva paĝo, la normala versia historio de paĝo ne estas sufiĉa por la sekvado de la variantoj. Pli vere versioj estas ankaŭ kopiataj el testa vikio aŭ de aparta provejo aŭ el fremda Vikia projekto kun la praversio; kaj denove reen.
  • Estas rekomendata tre mallonga priskribo de la funkcieco.
  • Je la fino staras la funkcioj, kiuj estas destinitaj por la eksporto.
  • p estas la redona valoro de la tuta modulo. Ĉi tiu nomo enradikiĝis, kaj ĝi prezentas table.

Funkcioj nur por ŝablonoj, sed ankaŭ internaj helpofunkcioj redakti

--[=[ ĈiTiuEkzemplo 2013-05-07
Ĉi tiu kaj tiu celoj
* service
]=]

-- Module globals
local messagePrefix = "lua-module-ĈiTiuEkzemplo-"
-- ...
-- ...

local function x( a )
    -- ...
    return r
end -- x()

-- ...
-- ...


-- Provide template access
local p = {}

p.service( frame )
    -- ...
    return x( u ) or ""
end -- .service()

return p

La funkcio service estas eksportata por uzado en ŝablono.

Funkcioj por ŝablonoj kaj aldona Lua-aliro redakti

--[=[ ĈiTiuEkzemplo 2013-05-07
Ĉi tiu kaj tiu celoj
* service
* ĈiTiuEkzemplo()
]=]

-- Module globals
local messagePrefix = "lua-module-ĈiTiuEkzemplo-"
local ĈiTiuEkzemplo = { }
-- ...
-- ...

local function x( a )
    -- ...
    return r
end -- x()


ĈiTiuEkzemplo.service = function ( a )
    -- ...
    return x( u )
end -- ĈiTiuEkzemplo.service()


-- ...
-- ...

-- Provide external access
local p = {}

p.service( frame )
    -- ...
    return ĈiTiuEkzemplo.service( u ) or ""
end -- .service()

function p.ĈiTiuEkzemplo()
    -- Retrieve function access for modules
    -- Postcondition:
    --     Return table with functions
    return ĈiTiuEkzemplo
end -- .ĈiTiuEkzemplo()

return p

Kiel antaŭe, sed aldone estas eksportata la table ĈiTiuEkzemplo per la funkcio ĈiTiuEkzemplo().

  • La funkcio ĈiTiuEkzemplo.service() disponeblas poste ankaŭ al aliaj moduloj.
  • La vera kodigo de la funkcieco okazas en ĈiTiuEkzemplo.service() kaj la funkcio service por ŝablonoj alvokas ĉi tiun kodigon. Ĉe tio estu konvene interpretataj la parametroj de la ŝablona enplekto (signoĉeno en frame.args) kaj ilia tipo eventuale konvene konvertata. Dum ke la redona valoro de ĈiTiuEkzemplo.service() ankaŭ falsenil povus esti, estas redonata per or "" tiu taŭga por ŝablonoj malplena signoĉeno.

Funkcioj eksklude por Lua-aliro, ne por ŝablono redakti

--[=[ ĈiTiuEkzemplo 2013-05-07
Ĉi tiu kaj tiu celoj
* ĈiTiuEkzemplo.service()
]=]

-- Module globals
local messagePrefix = "lua-module-ĈiTiuEkzemplo-"
local ĈiTiuEkzemplo = { }
-- ...
-- ...

local function x( a )
    -- ...
    return r
end -- x()


ĈiTiuEkzemplo.service = function ( a )
    -- ...
    return x( u )
end -- ĈiTiuEkzemplo.service()


-- ...
-- ...

-- Provide external access

return ĈiTiuEkzemplo

La eksporto de p kun la tabelo por ŝablonoj forfalas; estas nur la table ĈiTiuEkzemplo rekte eksportata.

Ĉi tiu situacio okazas ekzemple ĉe eligitaj submoduloj sed ankaŭ datumtabeloj ĉe mw.loadData().

Gepatra ĉirkaŭaĵo redakti

Provoj, esplori la programteknike principe ekzistantan gepatran ĉirkaŭaĵon, estas sisteme malebligataj de Scribunto kun la celo de la enkapsuligo. Per tio „Lua en Vikio“ diferencas de ĝeneralaj Lua-aplikaĵoj.

La ununura sencoplena ebla aliro eblas al la parametroj de la rekte enplektanta paĝo:
frame:getParent().args

Ene de la rekte ĉirkaŭanta paĝo (ŝablono) okazas la unuopaj alvokoj de #invoke sinsekve kaj sub uzado de la sama ĉirkaŭaĵo.

  • Malsamaj enplektoj de la ŝablono mem (ekz. en artikolo) kontraŭe estas paralele prilaborataj kaj ne dividas gepatran ĉirkaŭaĵon.

math.random() redakti

Antaŭ la unua alvoko de la funkcio math.random() estas pravalorizata la hazardnombra generilo ĉiam kun la valoro 0 (pri pravalorizado vidu math.randomseed()). Sen propra pravalorizado do ĉiam estas generata la sama sekvo de hazardaj nombroj. Ĉe sinsekva prilaborado de la alvokoj de #invoke ene de la sama ŝablono la hazardnombra generilo efektive ne estas rekomencigata intertempe, tiel ke la sekvo tie povas esti daŭrigata kontinue.

  1. Gerrit:58897