Modulmønstre og anbefalte fremgangsmåter
Bruk mønsteret local M = {} og eksponer et offentlig API på en ryddig måte.
Modulmønstre og anbefalte fremgangsmåter er en gratis leksjon i Lua Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Lua Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Lua Academy inneholder totalt 4 leksjoner.
Mønsteret M = {}
Det universelle Lua-modulmønsteret: deklarer en lokal tabell, fyll den med innhold og returner den. Alle offentlige symboler legges i M; alle private hjelpefunksjoner er vanlige lokale variabler. Dette er tydelig, minimalt og fungerer overalt.
-- The canonical module pattern
local M = {}
-- Private helper (not exported)
local function validate(x)
return type(x) == "number" and x >= 0
end
-- Public API
function M.sqrt(x)
assert(validate(x), "expected non-negative number")
return math.sqrt(x)
end
M.PI = math.pi
return MSelvrefererende modul
Inne i en modul kan funksjoner kalle andre modulf funksjoner enten via navn (M.foo()) eller som lokale funksjoner. Lokale funksjoner er litt raskere; bruk av M.foo() gjør det mulig for brukere å overstyre M.foo og få det interne kallet til å bruke overstyringen (monkey patching).
local M = {}
-- Option A: use M.foo inside (allows override)
function M.double(n) return M.multiply(n, 2) end
function M.multiply(a, b) return a * b end
-- Option B: use local function (faster, no override)
local function mul(a, b) return a * b end
function M.triple(n) return mul(n, 3) end
return MSingleton-mønsteret
En modul kan fungere som en singleton: den har en muterbar intern tilstand som deles av alle kallere. Siden require mellomlagrer modulen, får alle kall til require("mod") det samme objektet med den samme tilstanden.
-- config.lua (singleton)
local M = {}
local _config = {env="dev", logLevel="info"}
function M.set(key, val)
_config[key] = val
end
function M.get(key)
return _config[key]
end
function M.load(t)
for k,v in pairs(t) do _config[k]=v end
end
return M
-- All callers share the same config:Modul som navneområde
Bruk en modul utelukkende som et navneområde for å unngå å forurense den globale tabellen. Gruppér relaterte konstanter og hjelpefunksjoner under ett navn, slik en pakke gjør i andre språk.
-- constants.lua
local M = {
HTTP = {
OK=200, CREATED=201, NO_CONTENT=204,
BAD_REQUEST=400, UNAUTHORIZED=401,
NOT_FOUND=404, SERVER_ERROR=500,
},
COLORS = {RED="#FF0000", GREEN="#00FF00", BLUE="#0000FF"},
MAX_RETRIES = 3,
TIMEOUT_SEC = 30,
}
return M
-- local C = require("constants")
-- if status == C.HTTP.NOT_FOUND then ...Fabrikkmodul
En modul som eksporterer en fabrikkfunksjon i stedet for en vanlig tabell. Fabrikken oppretter og returnerer nye instanser med sin egen private tilstand. Dette er klassemønsteret på modulnivå.
-- logger.lua
local M = {}
function M.new(name, level)
level = level or "info"
local levels = {debug=1,info=2,warn=3,error=4}
local self = {}
function self.log(msgLevel, msg)
if levels[msgLevel] >= levels[level] then
print(string.format("[%s][%s] %s", name, msgLevel:upper(), msg))
end
end
function self.info(msg) self.log("info", msg) end
function self.warn(msg) self.log("warn", msg) end
function self.error(msg) self.log("error", msg) end
return self
end
return MInitialiseringsfunksjon for modul
Noen moduler krever konfigurasjon før de kan brukes. Tilby en M.init(config)-funksjon som lagrer konfigurasjonen i modulens private tilstand. Dette muliggjør avhengighetsinjeksjon og gjør testing enklere.
-- db.lua
local M = {}
local pool = nil
function M.init(config)
pool = {
host = config.host or "localhost",
port = config.port or 5432,
connections = {},
}
print("DB initialized:", pool.host, pool.port)
end
function M.query(sql)
assert(pool, "call db.init() first")
-- ... execute query
return {}
end
return MUforanderlig modul
Hindre brukere i å endre modulens API ved et uhell ved å bruke __newindex til å blokkere alle skrivinger. Dette er særlig nyttig for biblioteksmoduler der utilsiktet monkey patching kan ødelegge funksjonaliteten.
local function freeze(t)
return setmetatable({}, {
__index = t,
__newindex = function(_, k, _)
error("module is read-only, cannot set: " .. tostring(k), 2)
end
})
end
local M = {}
function M.add(a, b) return a + b end
function M.sub(a, b) return a - b end
return freeze(M)Dokumentere med LDoc
En vanlig konvensjon for dokumentasjon av Lua-moduler er kommentarer i LDoc-stil med prefikset ---. Selv om språket ikke håndhever dette, gjør kommentarene det mulig for verktøy for dokumentasjonsgenerering å opprette API-dokumentasjon automatisk.
--- A utility module for string operations.
-- @module stringutils
local M = {}
--- Trim leading and trailing whitespace.
-- @param s string The input string.
-- @return string The trimmed string.
function M.trim(s)
return s:match("^%s*(.-)%s*$")
end
--- Count occurrences of a substring.
-- @param str string The string to search.
-- @param sub string The substring to count.
-- @return number Count of occurrences.
function M.count(str, sub)
local _, n = str:gsub(sub, "")
return n
end
return MTeste moduler
Test en modul ved å kreve den og prøve ut hver funksjon. Bruk en enkel testrunner eller busted (testrammeverket for Lua). Oppbevar testene i en separat fil som speiler modulens sti.
-- test/test_stringutils.lua
local su = require("stringutils")
local function test(name, fn)
local ok, err = pcall(fn)
if ok then print("[PASS] " .. name)
else print("[FAIL] " .. name .. ": " .. err)
end
end
test("trim removes spaces", function()
assert(su.trim(" hello ") == "hello")
end)
test("trim empty string", function()
assert(su.trim("") == "")
end)
test("count occurrences", function()
assert(su.count("banana", "a") == 3)
end)Sette sammen moduler
Komplekse systemer settes sammen av flere moduler. Et hovedinngangspunkt krever og kobler sammen undermodulene. Denne ansvarsdelingen holder hver modul fokusert og gjør den mulig å teste uavhengig.
-- app.lua (main entry point)
local config = require("config")
local db = require("db")
local server = require("server")
-- Configure from environment
config.load({
dbHost = os.getenv("DB_HOST") or "localhost",
port = tonumber(os.getenv("PORT")) or 8080,
})
-- Wire modules together
db.init({host=config.get("dbHost"), port=5432})
server.init({port=config.get("port"), db=db})
server.start()Hurtigsjekk
Hva er hovedformålet med modulmønsteret local M = {} ... return M?
Oppsummering: Beste praksis for moduler
Oppsummering:
- Bruk alltid
local M = {} ... return M - Private = lokale variabler på filnivå; offentlige = M-felt
- Singleton: require mellomlagrer modulinstansen
- Bruk fabrikkfunksjoner for tilstand per instans
- Frys moduler med __newindex for å hindre endringer
- Test i separate filer; dokumenter med ----kommentarer
Lær deg Lua med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 40
- Leksjoner
- 159
Ofte stilte spørsmål
Er leksjonen «Modulmønstre og anbefalte fremgangsmåter» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Lua Academy, inkludert «Modulmønstre og anbefalte fremgangsmåter», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Lua Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Modulmønstre og anbefalte fremgangsmåter»?
Bruk mønsteret local M = {} og eksponer et offentlig API på en ryddig måte. Du øver på Lua Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Lua Academy?
Ingen tidligere erfaring er nødvendig. Lua Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.
Hvor lang tid tar leksjonen «Modulmønstre og anbefalte fremgangsmåter»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Lua Academy-leksjonen?
Ja. Alle Lua Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Funksjonen require
- Skrive en modulfil
- package.path og package.cpath
- Modulmønstre og anbefalte fremgangsmåter