레슨 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)) -- 0package.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으로 끝내는 패턴이 가장 깔끔합니다.