0Pricing
Lua Academy · Pelajaran

Menulis Berkas Modul

Buat modul dengan mengembalikan tabel berisi fungsi dari berkas .lua.

Menulis Berkas Modul adalah pelajaran Lua Academy gratis di CoddyKit. Ini adalah pelajaran 2 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 Modul Dasar

Pola modul Lua standar: buat tabel lokal M, tambahkan fungsi dan nilai ke dalamnya, lalu kembalikan tabel tersebut di akhir. Tabel ini adalah API publik modul. Semua lokal lainnya dalam berkas bersifat privat.

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

Status Privat

Variabel yang dideklarasikan sebagai local dalam berkas modul bersifat privat—pemanggil tidak dapat mengaksesnya. Fungsi dalam modul dapat mengakses status privat sebagai upvalue. Inilah mekanisme enkapsulasi 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

Modul dengan Inisialisasi

Beberapa modul memerlukan inisialisasi (konfigurasi, koneksi). Letakkan kode inisialisasi pada tingkat modul (di bagian atas berkas) atau dalam fungsi M.init() yang eksplisit. Pendekatan tingkat modul berjalan satu kali saat pertama kali diperlukan; init() memerlukan pemanggilan eksplisit.

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

Modul dengan Kelas

Sebuah modul dapat mengekspor kelas: tabel dengan fungsi konstruktor. Tabel modul yang dikembalikan berisi fungsi new() dan juga dapat berfungsi sebagai metatabel kelas.

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

Konstanta Modul

Ekspor konstanta dengan menambahkannya ke tabel modul. Menurut konvensi, konstanta ditulis dengan huruf kapital. Karena Lua tidak memiliki const, pengguna secara teknis dapat mengubahnya, tetapi penamaan dengan huruf kapital memberi isyarat "jangan diubah".

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

Pemberian Versi Modul

Sertakan kolom versi dalam modul Anda. Pemanggil dapat memeriksa versi untuk memastikan kompatibilitas. Gunakan pemberian versi semantik (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"))

Submodul

Pustaka besar dipecah menjadi submodul. Modul utama dapat memerlukan dan mengekspor ulang submodul, atau setiap submodul dapat digunakan secara terpisah. Atur berkas dalam direktori yang sesuai dengan jalur modul.

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

Modul dengan Metatabel

Buat modul dapat dipanggil dengan memberinya metatabel yang memiliki __call. Ini berguna untuk modul yang terutama berupa fungsi tetapi juga memiliki utilitas—operasi "utama" adalah pemanggilan, sedangkan utilitas adalah bidang.

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

Pemuatan Submodul secara Malas

Gunakan __index untuk memuat submodul secara malas—hanya saat pertama kali diakses. Hal ini mempercepat proses awal untuk pustaka besar dengan banyak submodul.

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

Pola Pengujian Modul

Tambahkan fungsi atau blok pengujian di bagian bawah berkas modul, yang dijalankan secara kondisional hanya saat berkas dijalankan secara langsung (bukan saat diperlukan). Dengan demikian, pengujian unit tetap berada bersama kodenya.

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

Pemeriksaan Cepat

Apa cara standar untuk mendefinisikan status privat dalam modul Lua?

Rangkuman: Menulis Modul

Ringkasan:

  • Pola: local M = {} ... return M
  • Lokal dalam berkas = privat; bidang M = API publik
  • Kode tingkat modul berjalan satu kali saat pertama kali diperlukan
  • Ekspor kelas melalui konstruktor dalam tabel modul
  • Pemuatan submodul secara malas melalui __index
  • Sertakan _VERSION untuk pemeriksaan kompatibilitas

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Menulis Berkas Modul” gratis?

Ya — teks lengkap “Menulis Berkas Modul” 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 “Menulis Berkas Modul”?

Buat modul dengan mengembalikan tabel berisi fungsi dari berkas .lua. 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 2 dari 4.

Berapa lama pelajaran “Menulis Berkas Modul” 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