0Pricing
Lua Academy · Lezione

Scrittura di un file di modulo

Crei un modulo restituendo una tabella di funzioni da un file .lua.

Scrittura di un file di modulo è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Lua Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Lua Academy include 4 lezioni in totale.

Il modello di modulo di base

Il modello standard per i moduli Lua consiste nel creare una tabella locale M, aggiungervi funzioni e valori e restituirla alla fine. La tabella costituisce l'API pubblica del modulo. Tutte le altre variabili locali del file sono private.

-- stringutils.lua
local M = {}

function M.trim(s)
  return s:match("^%s*(.-)%s*$")
end

function M.split(s, sep)
  local t = {}
  for p in s:gmatch("[^"..sep.."]+") do t[#t+1]=p end
  return t
end

return M

-- Usage:
-- local su = require("stringutils")
-- print(su.trim("  hello  "))

Stato privato

Le variabili dichiarate come local nel file del modulo sono private: chi lo utilizza non può accedervi. Le funzioni del modulo possono accedere allo stato privato come upvalue. Questo è il meccanismo di incapsulamento di Lua.

-- counter.lua
local M = {}
local count = 0   -- private state

function M.increment(n)
  count = count + (n or 1)
end

function M.reset()
  count = 0
end

function M.get()
  return count
end

return M

Modulo con inizializzazione

Alcuni moduli richiedono un'inizializzazione, ad esempio per la configurazione o le connessioni. Inserisca il codice di inizializzazione a livello di modulo (all'inizio del file) oppure in una funzione esplicita M.init(). L'approccio a livello di modulo viene eseguito una volta al primo require; init() richiede una chiamata esplicita.

-- cache.lua
local M = {}
local store = {}   -- initialized at load time
local hits = 0
local misses = 0

function M.get(key)
  if store[key] ~= nil then
    hits = hits + 1
    return store[key]
  end
  misses = misses + 1
  return nil
end

function M.set(key, val) store[key] = val end
function M.stats() return {hits=hits, misses=misses} end

return M

Modulo con classe

Un modulo può esportare una classe: una tabella con una funzione costruttrice. La tabella del modulo restituita contiene la funzione new() e può anche fungere da metatabella della classe.

-- point.lua
local Point = {}
Point.__index = Point

function Point.new(x, y)
  return setmetatable({x=x, y=y}, Point)
end

function Point:distance(other)
  local dx, dy = self.x-other.x, self.y-other.y
  return math.sqrt(dx*dx + dy*dy)
end

function Point:__tostring()
  return string.format("(%g,%g)", self.x, self.y)
end

return Point

-- Usage:
-- local Point = require("point")
-- local p = Point.new(3, 4)

Costanti del modulo

Esporti le costanti aggiungendole alla tabella del modulo. Per convenzione, le costanti sono scritte in maiuscolo. Poiché Lua non dispone di const, tecnicamente gli utenti possono modificarle, ma il nome in maiuscolo segnala di non cambiarle.

-- colors.lua
local M = {}

M.RED   = {r=255, g=0,   b=0}
M.GREEN = {r=0,   g=255, b=0}
M.BLUE  = {r=0,   g=0,   b=255}
M.WHITE = {r=255, g=255, b=255}
M.BLACK = {r=0,   g=0,   b=0}

function M.toHex(c)
  return string.format("#%02X%02X%02X", c.r, c.g, c.b)
end

return M

Versionamento dei moduli

Includa un campo di versione nel modulo. Chi lo utilizza può controllare la versione per verificare la compatibilità. Usi il versionamento semantico (major.minor.patch).

-- mylib.lua
local M = {}
M._VERSION = "1.2.3"
M._NAME = "mylib"
M._DESCRIPTION = "My Lua library"

function M.hello(name)
  return "Hello, " .. (name or "World") .. "!"
end

return M

-- Usage:
local mylib = require("mylib")
print(mylib._VERSION)   -- 1.2.3
print(mylib.hello("Lua"))

Sottomoduli

Le librerie di grandi dimensioni vengono suddivise in sottomoduli. Il modulo principale può richiedere e riesportare i sottomoduli, oppure ogni sottomodulo può essere usato indipendentemente. Organizzi i file in directory corrispondenti al percorso del modulo.

-- mylib/init.lua  (loaded by require("mylib"))
local M = {}

M.strings = require("mylib.strings")
M.tables  = require("mylib.tables")
M.math    = require("mylib.math")

M._VERSION = "2.0.0"

return M

-- Users can require the whole library:
-- local mylib = require("mylib")
-- mylib.strings.trim(...)

-- Or individual sub-modules:
-- local strs = require("mylib.strings")

Modulo con metatabella

Renda chiamabile un modulo assegnandogli una metatabella con __call. È utile per i moduli costituiti principalmente da funzioni ma dotati anche di utility: l'operazione principale è la chiamata, mentre le utility sono campi.

-- format.lua
local M = {}
setmetatable(M, {__call = function(_, fmt, ...)
  return string.format(fmt, ...)
end})

function M.pad(s, width, char)
  char = char or " "
  return string.rep(char, math.max(0, width - #s)) .. s
end

return M

-- Usage:
-- local fmt = require("format")
-- print(fmt("%.2f", 3.14))   -- 3.14
-- print(fmt.pad("42", 5))    --    42

Caricamento differito dei sottomoduli

Usi __index per caricare i sottomoduli in modo differito, solo al primo accesso. Questo accelera l'avvio delle librerie di grandi dimensioni con molti sottomoduli.

-- biglib.lua
local M = {}
local submodules = {"strings", "tables", "math", "io"}

setmetatable(M, {
  __index = function(t, k)
    for _, name in ipairs(submodules) do
      if name == k then
        local mod = require("biglib." .. k)
        rawset(t, k, mod)
        return mod
      end
    end
    return nil
  end
})

return M

-- Loads biglib.strings only when accessed:
-- local lib = require("biglib")
-- lib.strings.trim(...)

Modello per i test dei moduli

Aggiunga una funzione o un blocco di test in fondo al file del modulo, eseguito condizionalmente solo quando il file viene eseguito direttamente (e non quando viene richiesto). In questo modo i test unitari rimangono insieme al codice.

-- utils.lua
local M = {}

function M.clamp(v, lo, hi)
  return math.max(lo, math.min(hi, v))
end

-- Self-test: only runs when executed directly
if debug.getinfo(2, "S") == nil then
  -- Running as main script, not required
  print("Testing clamp...")
  assert(M.clamp(5, 0, 10) == 5)
  assert(M.clamp(-1, 0, 10) == 0)
  assert(M.clamp(15, 0, 10) == 10)
  print("All tests passed!")
end

return M

Verifica rapida

Qual è il modo standard per definire lo stato privato in un modulo Lua?

Riepilogo: scrivere moduli

Riepilogo:

  • Modello: local M = {} ... return M
  • Variabili locali nel file = private; campi di M = API pubblica
  • Il codice a livello di modulo viene eseguito una volta al primo require
  • Esporti le classi tramite un costruttore nella tabella del modulo
  • Caricamento differito dei sottomoduli tramite __index
  • Includa _VERSION per i controlli di compatibilità

Domande Frequenti

La lezione «Scrittura di un file di modulo» è gratuita?

Sì — il testo completo di «Scrittura di un file di modulo» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Lua Academy, passa a CoddyKit PRO. Il corso Lua Academy include 4 lezioni in totale.

Cosa imparerò in «Scrittura di un file di modulo»?

Crei un modulo restituendo una tabella di funzioni da un file .lua. Eserciti Lua Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Lua Academy?

Non è richiesta alcuna esperienza precedente. Lua Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Scrittura di un file di modulo»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Lua Academy?

Sì. Ogni lezione Lua Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. La funzione require
  2. Scrittura di un file di modulo
  3. package.path e package.cpath
  4. Pattern e buone pratiche per i moduli
← Torna a Lua Academy