0Pricing
Lua Academy · Lekcja

Tworzenie pliku modułu

Proszę utworzyć moduł, zwracając tabelę funkcji z pliku .lua.

Tworzenie pliku modułu to bezpłatna lekcja Lua Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Lua Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Lua Academy zawiera 4 lekcji w sumie.

Podstawowy wzorzec modułu

Standardowy wzorzec modułu w Lua polega na utworzeniu lokalnej tabeli M, dodaniu do niej funkcji i wartości, a następnie zwróceniu jej na końcu. Tabela stanowi publiczne API modułu. Wszystkie pozostałe zmienne lokalne w pliku są prywatne.

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

Stan prywatny

Zmienne zadeklarowane jako local w pliku modułu są prywatne — wywołujący nie mogą uzyskać do nich dostępu. Funkcje modułu mogą uzyskiwać dostęp do prywatnego stanu za pośrednictwem zmiennych upvalue. Jest to mechanizm enkapsulacji w 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

Moduł z inicjalizacją

Niektóre moduły wymagają inicjalizacji (na przykład konfiguracji lub połączeń). Kod inicjalizacyjny można umieścić na poziomie modułu (na początku pliku) albo w jawnej funkcji M.init(). Wariant z kodem na poziomie modułu wykonuje się raz przy pierwszym użyciu require, natomiast init() wymaga jawnego wywołania.

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

Moduł z klasą

Moduł może eksportować klasę, czyli tabelę z funkcją konstruktora. Zwracana tabela modułu zawiera funkcję new() i może również służyć jako metatabela klasy.

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

Stałe modułu

Eksportuj stałe, dodając je do tabeli modułu. Zgodnie z konwencją stałe zapisuje się wielkimi literami. Ponieważ Lua nie ma słowa kluczowego const, użytkownicy mogą je technicznie modyfikować, ale zapis wielkimi literami sygnalizuje „nie zmieniaj”.

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

Wersjonowanie modułu

Umieść w module pole z numerem wersji. Wywołujący mogą sprawdzać wersję, aby upewnić się, że jest zgodna. Używaj wersjonowania semantycznego (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"))

Podmoduły

Duże biblioteki dzieli się na podmoduły. Główny moduł może wymagać podmodułów i ponownie je eksportować albo każdy podmoduł może być używany niezależnie. Organizuj pliki w katalogach odpowiadających ścieżce modułu.

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

Moduł z metatabelą

Moduł można uczynić wywoływalnym, nadając mu metatabelę z polem __call. Jest to przydatne w przypadku modułów, które są przede wszystkim funkcjami, ale zawierają również narzędzia — „główną” operacją jest wywołanie, a narzędzia są polami.

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

Leniwe ładowanie podmodułów

Użyj __index, aby leniwie ładować podmoduły — dopiero przy ich pierwszym użyciu. Przyspiesza to uruchamianie dużych bibliotek zawierających wiele podmodułów.

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

Wzorzec testowania modułu

Dodaj funkcję testową lub blok na końcu pliku modułu i wykonuj go warunkowo tylko wtedy, gdy plik jest uruchamiany bezpośrednio (a nie wymagany). Dzięki temu testy jednostkowe znajdują się razem z kodem.

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

Szybkie sprawdzenie

Jaki jest standardowy sposób definiowania prywatnego stanu w module Lua?

Podsumowanie: pisanie modułów

Podsumowanie:

  • Wzorzec: local M = {} ... return M
  • Zmienne lokalne w pliku = elementy prywatne; pola M = publiczne API
  • Kod na poziomie modułu wykonuje się raz przy pierwszym użyciu require
  • Eksportuj klasy za pomocą konstruktora w tabeli modułu
  • Leniwe ładowanie podmodułów za pomocą __index
  • Dodaj _VERSION na potrzeby sprawdzania zgodności

Często zadawane pytania

Czy lekcja „Tworzenie pliku modułu” jest bezpłatna?

Tak — pełny tekst „Tworzenie pliku modułu” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Lua Academy, przejdź na CoddyKit PRO. Kurs Lua Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Tworzenie pliku modułu”?

Proszę utworzyć moduł, zwracając tabelę funkcji z pliku .lua. Ćwiczysz Lua Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Lua Academy?

Nie wymagamy żadnego doświadczenia. Lua Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Tworzenie pliku modułu”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Lua Academy?

Tak. Każda lekcja Lua Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Funkcja require
  2. Tworzenie pliku modułu
  3. package.path i package.cpath
  4. Wzorce modułów i dobre praktyki
← Powrót do Lua Academy