0Pricing
Lua Academy · 강의

모듈 파일 작성

.lua 파일에서 함수 테이블을 반환해 모듈을 만듭니다.

모듈 파일 작성은(는) CoddyKit의 무료 Lua Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Lua Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Lua Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

기본 모듈 패턴

Lua의 표준 모듈 패턴은 로컬 테이블 M을 만들고, 여기에 함수와 값을 추가한 다음 마지막에 반환하는 방식입니다. 이 테이블이 모듈의 공개 API입니다. 파일의 다른 모든 로컬 항목은 비공개입니다.

-- 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  "))

비공개 상태

모듈 파일에서 local로 선언한 변수는 비공개이므로 호출자가 액세스할 수 없습니다. 모듈의 함수는 업밸류를 통해 비공개 상태에 액세스할 수 있습니다. 이것이 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.init() 함수에 넣으십시오. 모듈 수준 방식은 처음 require될 때 한 번 실행되고, init() 방식은 명시적으로 호출해야 합니다.

-- 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

클래스가 있는 모듈

모듈은 클래스를 내보낼 수 있습니다. 클래스는 생성자 함수를 포함한 테이블입니다. 반환되는 모듈 테이블에는 new() 함수가 포함되며, 클래스 메타테이블로도 사용할 수 있습니다.

-- 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)

모듈 상수

상수를 모듈 테이블에 추가하여 내보내십시오. 관례상 상수는 대문자로 작성합니다. Lua에는 const가 없으므로 사용자가 기술적으로 상수 값을 수정할 수 있지만, 대문자 이름은 "변경하지 말 것"을 나타냅니다.

-- 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

모듈 버전 관리

모듈에 버전 필드를 포함하십시오. 호출자는 버전을 확인하여 호환성을 보장할 수 있습니다. 시맨틱 버전 관리(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"))

하위 모듈

대규모 라이브러리는 하위 모듈로 나눕니다. 주 모듈이 하위 모듈을 require하여 다시 내보낼 수도 있고, 각 하위 모듈을 독립적으로 사용할 수도 있습니다. 모듈 경로에 맞는 디렉터리에 파일을 구성하십시오.

-- 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")

메타테이블이 있는 모듈

모듈에 __call이 포함된 메타테이블을 지정하면 모듈을 호출 가능하게 만들 수 있습니다. 이는 주로 함수로 사용되지만 유틸리티도 제공하는 모듈에 유용합니다. 즉, "주" 작업은 호출이고 유틸리티는 필드입니다.

-- 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

하위 모듈 지연 로딩

__index를 사용하면 하위 모듈을 지연 로드할 수 있습니다. 즉, 하위 모듈에 처음 액세스할 때만 로드합니다. 하위 모듈이 많은 대규모 라이브러리의 시작 시간을 줄이는 데 유용합니다.

-- 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(...)

모듈 테스트 패턴

모듈 파일의 끝에 테스트 함수나 블록을 추가하고, 파일을 직접 실행할 때만( require하지 않을 때만) 조건부로 실행하십시오. 이렇게 하면 단위 테스트를 코드와 같은 위치에 둘 수 있습니다.

-- 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

빠른 확인

Lua 모듈에서 비공개 상태를 정의하는 표준 방법은 무엇입니까?

복습: 모듈 작성

요약:

  • 패턴: local M = {} ... return M
  • 파일의 로컬 항목 = 비공개, M 필드 = 공개 API
  • 모듈 수준 코드는 처음 require될 때 한 번 실행됩니다
  • 모듈 테이블의 생성자를 통해 클래스를 내보냅니다
  • __index를 통한 하위 모듈 지연 로딩
  • 호환성 확인을 위해 _VERSION을 포함합니다

자주 묻는 질문

“모듈 파일 작성” 강의는 무료인가요?

네 — “모듈 파일 작성” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Lua Academy 강의 전체를 잠금 해제할 수 있습니다. Lua Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“모듈 파일 작성”에서 뭘 배우나요?

.lua 파일에서 함수 테이블을 반환해 모듈을 만듭니다. 브라우저에서 직접 실행하는 실습 코드로 Lua Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Lua Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Lua Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“모듈 파일 작성” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Lua Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Lua Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. require 함수
  2. 모듈 파일 작성
  3. package.path와 package.cpath
  4. 모듈 패턴과 모범 사례
← Lua Academy(으)로 돌아가기