Escritura de un archivo de módulo
Cree un módulo devolviendo una tabla de funciones desde un archivo .lua.
Escritura de un archivo de módulo es una lección gratuita de Lua Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Lua Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Lua Academy incluye 4 lecciones en total.
El patrón básico de módulo
El patrón estándar de módulos de Lua consiste en crear una tabla local M, añadirle funciones y valores, y devolverla al final. La tabla es la API pública del módulo. Todas las demás variables locales del archivo son privadas.
-- 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 "))Estado privado
Las variables declaradas como local en el archivo del módulo son privadas: quienes llaman al módulo no pueden acceder a ellas. Las funciones del módulo pueden acceder al estado privado como upvalues. Este es el mecanismo de encapsulación de 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 MMódulo con inicialización
Algunos módulos necesitan inicialización (configuración o conexiones). Coloque el código de inicialización a nivel del módulo (al principio del archivo) o en una función explícita M.init(). El enfoque a nivel del módulo se ejecuta una vez, cuando se requiere el módulo por primera vez; init() requiere una llamada explícita.
-- 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 MMódulo con clase
Un módulo puede exportar una clase: una tabla con una función constructora. La tabla del módulo devuelta contiene la función new() y también puede servir como metatabla de la clase.
-- 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)Constantes del módulo
Exporte constantes añadiéndolas a la tabla del módulo. Por convención, las constantes se escriben en mayúsculas. Como Lua no tiene const, técnicamente los usuarios pueden modificarlas, pero el uso de mayúsculas indica «no modificar».
-- 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 MVersionado de módulos
Incluya un campo de versión en el módulo. Quienes lo utilicen pueden comprobar la versión para garantizar la compatibilidad. Use versionado semántico (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"))Submódulos
Las bibliotecas grandes se dividen en submódulos. El módulo principal puede requerir y volver a exportar los submódulos, o cada submódulo puede utilizarse de forma independiente. Organice los archivos en directorios que correspondan a la ruta del módulo.
-- 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")Módulo con metatabla
Haga que un módulo sea invocable asignándole una metatabla con __call. Esto resulta útil para módulos que son principalmente funciones, pero que también tienen utilidades: la operación «principal» es la llamada y las utilidades son campos.
-- 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)) -- 42Carga diferida de submódulos
Use __index para cargar submódulos de forma diferida, solo cuando se acceda a ellos por primera vez. Esto acelera el inicio de bibliotecas grandes con muchos submódulos.
-- 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(...)Patrón de pruebas de módulos
Añada una función o un bloque de prueba al final del archivo del módulo, que se ejecute condicionalmente solo cuando el archivo se ejecute directamente (y no cuando se requiera). Así, las pruebas unitarias permanecen junto al código.
-- 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 MComprobación rápida
¿Cuál es la forma estándar de definir un estado privado en un módulo de Lua?
Resumen: escritura de módulos
Resumen:
- Patrón:
local M = {} ... return M - Las variables locales del archivo son privadas; los campos de M forman la API pública
- El código a nivel del módulo se ejecuta una vez, al requerirlo por primera vez
- Exporte clases mediante un constructor en la tabla del módulo
- Carga diferida de submódulos mediante
__index - Incluya
_VERSIONpara comprobar la compatibilidad
Preguntas frecuentes
¿La lección «Escritura de un archivo de módulo» es gratis?
Sí — el texto completo de «Escritura de un archivo de módulo» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Lua Academy, actualiza a CoddyKit PRO. El curso de Lua Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Escritura de un archivo de módulo»?
Cree un módulo devolviendo una tabla de funciones desde un archivo .lua. Practicas Lua Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Lua Academy?
No se requiere experiencia previa. Lua Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Escritura de un archivo de módulo»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Lua Academy?
Sí. Cada lección de Lua Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- La función require
- Escritura de un archivo de módulo
- package.path y package.cpath
- Patrones de módulos y buenas prácticas