0Pricing
Lua Academy · Aula

Escrevendo um arquivo de módulo

Crie um módulo retornando uma tabela de funções a partir de um arquivo .lua.

Escrevendo um arquivo de módulo é uma aula grátis de Lua Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Lua Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Lua Academy inclui 4 aulas no total.

O padrão básico de módulo

O padrão padrão de módulo Lua: crie uma tabela local M, adicione funções e valores a ela e retorne-a no final. A tabela é a API pública do módulo. Todas as outras variáveis locais do arquivo são 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

As variáveis declaradas como local no arquivo do módulo são privadas — os chamadores não podem acessá-las. As funções do módulo podem acessar o estado privado como valores capturados. Esse é o mecanismo de encapsulamento 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 M

Módulo com inicialização

Alguns módulos precisam de inicialização (configuração, conexões). Coloque o código de inicialização no nível do módulo (no início do arquivo) ou em uma função explícita M.init(). A abordagem no nível do módulo é executada uma vez, quando o módulo é requerido pela primeira vez; init() exige uma chamada 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 M

Módulo com classe

Um módulo pode exportar uma classe: uma tabela com uma função construtora. A tabela do módulo retornada contém a função new() e também pode servir como metatabela da 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)

Constantes do módulo

Exporte constantes adicionando-as à tabela do módulo. Por convenção, as constantes são escritas em maiúsculas. Como Lua não tem const, os usuários tecnicamente podem modificá-las, mas o nome em maiúsculas sinaliza “não altere”.

-- 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 de módulos

Inclua um campo de versão no seu módulo. Os chamadores podem verificar a versão para garantir a compatibilidade. Use versionamento 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

Bibliotecas grandes são divididas em submódulos. O módulo principal pode requerer e reexportar submódulos, ou cada submódulo pode ser usado de forma independente. Organize os arquivos em diretórios correspondentes ao caminho do 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 com metatabela

Torne um módulo chamável atribuindo-lhe uma metatabela com __call. Isso é útil para módulos que são principalmente funções, mas também têm utilitários — a operação “principal” é a chamada, e os utilitários são 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))    --    42

Carregamento tardio de submódulos

Use __index para carregar submódulos de forma tardia — somente quando forem acessados pela primeira vez. Isso acelera a inicialização de bibliotecas grandes com muitos 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(...)

Padrão de testes de módulos

Adicione uma função ou um bloco de teste na parte inferior do arquivo do módulo, executado condicionalmente somente quando o arquivo for executado diretamente (e não requerido). Isso mantém os testes unitários junto do 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 M

Verificação rápida

Qual é a maneira padrão de definir um estado privado em um módulo Lua?

Recapitulação: escrevendo módulos

Resumo:

  • Padrão: local M = {} ... return M
  • Variáveis locais no arquivo = privadas; campos de M = API pública
  • O código no nível do módulo é executado uma vez, no primeiro require
  • Exporte classes por meio de uma função construtora na tabela do módulo
  • Carregamento tardio de submódulos por meio de __index
  • Inclua _VERSION para verificações de compatibilidade

Perguntas Frequentes

A aula “Escrevendo um arquivo de módulo” é grátis?

Sim — o texto completo de “Escrevendo um arquivo de módulo” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Lua Academy, atualize para CoddyKit PRO. O curso de Lua Academy inclui 4 aulas no total.

O que vou aprender em “Escrevendo um arquivo de módulo”?

Crie um módulo retornando uma tabela de funções a partir de um arquivo .lua. Você pratica Lua Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Lua Academy?

Nenhuma experiência prévia é necessária. Lua Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “Escrevendo um arquivo de módulo”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Lua Academy?

Sim. Cada aula de Lua Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. A função require
  2. Escrevendo um arquivo de módulo
  3. package.path e package.cpath
  4. Padrões e boas práticas para módulos
← Voltar para Lua Academy