0Pricing
Lua Academy · Pelajaran

Pola Modul dan Praktik Terbaik

Gunakan pola local M = {} dan tampilkan API publik dengan rapi.

Pola Modul dan Praktik Terbaik adalah pelajaran Lua Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Lua Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Lua Academy mencakup 4 pelajaran total.

Pola M = {}

Pola modul Lua universal: deklarasikan tabel lokal, isi tabel tersebut, lalu kembalikan. Semua simbol publik dimasukkan ke M; semua pembantu privat berupa lokal biasa. Pola ini jelas, minimal, dan dapat digunakan di mana saja.

-- The canonical module pattern
local M = {}

-- Private helper (not exported)
local function validate(x)
  return type(x) == "number" and x >= 0
end

-- Public API
function M.sqrt(x)
  assert(validate(x), "expected non-negative number")
  return math.sqrt(x)
end

M.PI = math.pi

return M

Modul yang Mereferensikan Dirinya

Di dalam modul, fungsi dapat memanggil fungsi modul lainnya berdasarkan nama (M.foo()) atau sebagai lokal. Menggunakan lokal sedikit lebih cepat; menggunakan M.foo() memungkinkan pengguna mengganti M.foo dan membuat pemanggilan internal menggunakan penggantinya (penambalan monyet).

local M = {}

-- Option A: use M.foo inside (allows override)
function M.double(n) return M.multiply(n, 2) end
function M.multiply(a, b) return a * b end

-- Option B: use local function (faster, no override)
local function mul(a, b) return a * b end
function M.triple(n) return mul(n, 3) end

return M

Pola Singleton

Sebuah modul dapat bertindak sebagai singleton: modul tersebut memiliki status internal yang dapat diubah dan dibagikan oleh semua pemanggil. Karena require menyimpan modul dalam tembolok, semua pemanggilan require("mod") memperoleh objek yang sama dengan status yang sama.

-- config.lua (singleton)
local M = {}
local _config = {env="dev", logLevel="info"}

function M.set(key, val)
  _config[key] = val
end

function M.get(key)
  return _config[key]
end

function M.load(t)
  for k,v in pairs(t) do _config[k]=v end
end

return M

-- All callers share the same config:

Modul sebagai Ruang Nama

Gunakan modul semata-mata sebagai ruang nama agar tabel global tidak tercemar. Kelompokkan konstanta dan utilitas terkait di bawah satu nama, seperti paket dalam bahasa lain.

-- constants.lua
local M = {
  HTTP = {
    OK=200, CREATED=201, NO_CONTENT=204,
    BAD_REQUEST=400, UNAUTHORIZED=401,
    NOT_FOUND=404, SERVER_ERROR=500,
  },
  COLORS = {RED="#FF0000", GREEN="#00FF00", BLUE="#0000FF"},
  MAX_RETRIES = 3,
  TIMEOUT_SEC = 30,
}
return M

-- local C = require("constants")
-- if status == C.HTTP.NOT_FOUND then ...

Modul Pabrik

Modul yang mengekspor fungsi pabrik, bukan tabel biasa. Pabrik membuat dan mengembalikan instans baru dengan status privatnya masing-masing. Ini adalah pola kelas pada tingkat modul.

-- logger.lua
local M = {}

function M.new(name, level)
  level = level or "info"
  local levels = {debug=1,info=2,warn=3,error=4}
  local self = {}
  
  function self.log(msgLevel, msg)
    if levels[msgLevel] >= levels[level] then
      print(string.format("[%s][%s] %s", name, msgLevel:upper(), msg))
    end
  end
  
  function self.info(msg)  self.log("info",  msg) end
  function self.warn(msg)  self.log("warn",  msg) end
  function self.error(msg) self.log("error", msg) end
  
  return self
end

return M

Fungsi Init Modul

Beberapa modul memerlukan konfigurasi sebelum digunakan. Sediakan fungsi M.init(config) yang menyimpan konfigurasi dalam status privat modul. Hal ini memungkinkan injeksi dependensi dan kemudahan pengujian.

-- db.lua
local M = {}
local pool = nil

function M.init(config)
  pool = {
    host = config.host or "localhost",
    port = config.port or 5432,
    connections = {},
  }
  print("DB initialized:", pool.host, pool.port)
end

function M.query(sql)
  assert(pool, "call db.init() first")
  -- ... execute query
  return {}
end

return M

Modul Takberubah

Cegah pengguna mengubah API modul secara tidak sengaja dengan menggunakan __newindex untuk memblokir semua penulisan. Ini sangat berguna untuk modul pustaka karena penambalan monyet yang tidak disengaja dapat merusak berbagai hal.

local function freeze(t)
  return setmetatable({}, {
    __index = t,
    __newindex = function(_, k, _)
      error("module is read-only, cannot set: " .. tostring(k), 2)
    end
  })
end

local M = {}
function M.add(a, b) return a + b end
function M.sub(a, b) return a - b end

return freeze(M)

Mendokumentasikan dengan LDoc

Konvensi umum untuk mendokumentasikan modul Lua adalah komentar bergaya LDoc dengan awalan ---. Meskipun tidak diwajibkan oleh bahasa, komentar ini memungkinkan alat pembuat dokumentasi menghasilkan dokumentasi API secara otomatis.

--- A utility module for string operations.
-- @module stringutils
local M = {}

--- Trim leading and trailing whitespace.
-- @param s string The input string.
-- @return string The trimmed string.
function M.trim(s)
  return s:match("^%s*(.-)%s*$")
end

--- Count occurrences of a substring.
-- @param str string The string to search.
-- @param sub string The substring to count.
-- @return number Count of occurrences.
function M.count(str, sub)
  local _, n = str:gsub(sub, "")
  return n
end

return M

Menguji Modul

Uji modul dengan memerlukannya dan menjalankan setiap fungsi. Gunakan pelari pengujian sederhana atau busted (kerangka kerja pengujian Lua). Simpan pengujian dalam berkas terpisah yang mencerminkan jalur modul.

-- test/test_stringutils.lua
local su = require("stringutils")

local function test(name, fn)
  local ok, err = pcall(fn)
  if ok then print("[PASS] " .. name)
  else   print("[FAIL] " .. name .. ": " .. err)
  end
end

test("trim removes spaces", function()
  assert(su.trim("  hello  ") == "hello")
end)

test("trim empty string", function()
  assert(su.trim("") == "")
end)

test("count occurrences", function()
  assert(su.count("banana", "a") == 3)
end)

Menyusun Modul

Sistem kompleks menyusun beberapa modul. Titik masuk utama memerlukan dan menghubungkan submodul. Pemisahan tanggung jawab ini membuat setiap modul tetap terfokus dan dapat diuji secara mandiri.

-- app.lua (main entry point)
local config = require("config")
local db     = require("db")
local server = require("server")

-- Configure from environment
config.load({
  dbHost = os.getenv("DB_HOST") or "localhost",
  port   = tonumber(os.getenv("PORT")) or 8080,
})

-- Wire modules together
db.init({host=config.get("dbHost"), port=5432})
server.init({port=config.get("port"), db=db})
server.start()

Pemeriksaan Cepat

Apa tujuan utama pola modul local M = {} ... return M?

Rangkuman: Praktik Terbaik Modul

Ringkasan:

  • Selalu gunakan local M = {} ... return M
  • Privat = lokal tingkat berkas; publik = bidang M
  • Singleton: require menyimpan instans modul dalam tembolok
  • Gunakan fungsi pabrik untuk status per instans
  • Bekukan modul dengan __newindex untuk mencegah perubahan
  • Uji dalam berkas terpisah; dokumentasikan dengan komentar ---

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Pola Modul dan Praktik Terbaik” gratis?

Ya — teks lengkap “Pola Modul dan Praktik Terbaik” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Lua Academy, upgrade ke CoddyKit PRO. Kursus Lua Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Pola Modul dan Praktik Terbaik”?

Gunakan pola local M = {} dan tampilkan API publik dengan rapi. Kamu berlatih Lua Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Lua Academy?

Tidak diperlukan pengalaman sebelumnya. Lua Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.

Berapa lama pelajaran “Pola Modul dan Praktik Terbaik” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Lua Academy ini?

Ya. Setiap pelajaran Lua Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Fungsi require
  2. Menulis Berkas Modul
  3. package.path dan package.cpath
  4. Pola Modul dan Praktik Terbaik
← Kembali ke Lua Academy