CodeRigor

FREE LESSON

Modules, local state & error contracts

Export a module table, keep globals clean and choose returned error values or protected calls deliberately.

Before this lesson, complete lua-strings-patterns.

This course runs standard Lua 5.5 with its standard library. Game engines, LuaJIT and embedded host APIs are outside this sequence.

A simple Lua module creates a local table, assigns exported functions to it and returns it from the chunk. Require loads the module through package searchers and caches the returned value in package.loaded. Requiring the same module again normally returns that cached value instead of re-executing its top-level code. This gives a stable API object without publishing every helper globally.

Load a module once
start / 3
Load a module once

Apply the contract

Keep implementation variables local. M = {} at top level writes a global; local M = {} creates a module-local table. A caller should receive the module through require rather than by searching _G for accidental names. Standard Lua package loading is available in the lab, while external libraries and application frameworks are not part of this course's execution contract.

Keep internals local
start / 3
Keep internals local
Lua
local function parse(text)
  local n=tonumber(text)
  if not n then return nil,"invalid" end
  return n
end
local value,err=parse("bad")
print(value,err)
local ok=pcall(function() error("demonstration") end)
print(ok)

Reason about the edge cases

Separate expected input errors from broken programming preconditions. This parser treats malformed or out-of-range input as ordinary data and returns nil, "invalid". Callers can branch on the first result and inspect the second. Error and assert instead raise an error; pcall can contain that control flow when appropriate. Validate string type and digit grammar before tonumber, then validate the positive bounded result. Leading zeroes are permitted by this contract, whereas zero itself is not. The fixtures check both result values, repeated require identity and the absence of a leaked global M. Good error behavior is part of the public API, not just a diagnostic printed on screen.

Two error interfaces
start / 3
Two error interfaces

Practice

Export M.parse_positive(text) from the solution module. Accept only a string of decimal digits whose numeric value is 1 through 1,000,000, returning that number. Otherwise return nil and the exact error string invalid. Leading zeroes are allowed. Do not create a global M or print during module loading. Requiring the module again must return its cached module table.

Run sample starts again from the first public fixture and grants no mastery evidence. Submit checks all fixtures, including edge cases. Read the specification before editing; the bug and fill phases share the build’s contract. Flashcards reinforce recall on a separate schedule.

Watch & read

Free lectures, talks and readings that cover this skill from another angle. All resources →

The first part introduces Lua through its language designer. The authored lesson and Lua 5.5 manual cover the exact APIs and advanced details in this lab.