Learning
레슨 5 / 8·3개 토픽

모듈과 패키지

모듈 만들기

Lua에서 모듈은 테이블을 반환하는 파일입니다. require()로 다른 파일의 모듈을 불러올 수 있으며, 한 번 로드된 모듈은 package.loaded에 캐시되어 재사용됩니다.

lua
-- mathutil.lua — 모듈 파일
local M = {}  -- 모듈 테이블

function M.add(a, b)
    return a + b
end

function M.subtract(a, b)
    return a - b
end

function M.clamp(value, min, max)
    if value < min then return min end
    if value > max then return max end
    return value
end

-- 비공개 함수 (M에 넣지 않으면 외부에서 접근 불가)
local function validate(n)
    return type(n) == "number"
end

function M.safe_divide(a, b)
    if not validate(a) or not validate(b) then
        return nil, "숫자가 아닙니다"
    end
    if b == 0 then
        return nil, "0으로 나눌 수 없습니다"
    end
    return a / b
end

return M  -- 모듈 테이블 반환

require()로 모듈 사용하기

lua
-- main.lua — 모듈 사용
local mathutil = require("mathutil")

print(mathutil.add(3, 5))        -- 8
print(mathutil.clamp(150, 0, 100))  -- 100

local result, err = mathutil.safe_divide(10, 0)
if not result then
    print("에러: " .. err)  -- "에러: 0으로 나눌 수 없습니다"
end

-- 특정 함수만 가져오기
local clamp = require("mathutil").clamp
print(clamp(-5, 0, 100))  -- 0

package.path와 모듈 캐싱

require()package.path에 지정된 경로에서 모듈 파일을 검색합니다. ?가 모듈 이름으로 치환됩니다. 모듈은 최초 1회만 로드되며, 이후에는 package.loaded에서 캐시된 결과를 반환합니다.

lua
-- 모듈 검색 경로 확인
print(package.path)
-- ./?.lua;/usr/local/share/lua/5.4/?.lua;...

-- 커스텀 경로 추가
package.path = package.path .. ";./libs/?.lua"

-- 모듈 캐싱 확인
local m1 = require("mathutil")
local m2 = require("mathutil")
print(m1 == m2)  -- true (같은 테이블, 재로드 안 함)

-- 캐시 삭제 후 재로드
package.loaded["mathutil"] = nil
local m3 = require("mathutil")
print(m1 == m3)  -- false (새로 로드됨)

-- 로드된 모듈 목록 확인
for name, _ in pairs(package.loaded) do
    print("로드됨: " .. name)
end
  • require("name") — 모듈 로드 (캐시 우선)
  • package.path — Lua 모듈 검색 경로 (?가 이름으로 치환)
  • package.loaded — 로드된 모듈 캐시 테이블
  • return M — 모듈 파일 끝에서 테이블 반환 (필수 패턴)
  • 로컬 함수는 모듈 테이블에 넣지 않으면 비공개
💡

모듈 파일에서 전역 변수 사용을 피하세요. local M = {}로 시작하고 return M으로 끝내는 패턴이 가장 깔끔합니다.