Lua Academy · Oppitunti

Moduulitiedoston kirjoittaminen

Luokaa moduuli palauttamalla funktioiden taulukko .lua-tiedostosta.

Oppitunti 2/412 vaihetta

Moduulitiedoston kirjoittaminen on ilmainen Lua Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Lua Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Lua Academy-kurssilla on yhteensä 4 oppituntia.

Moduulin perusmalli

Lua-moduulien vakiomalli on seuraava: luokaa paikallinen taulukko M, lisätkää siihen funktioita ja arvoja ja palauttakaa se lopuksi. Taulukko on moduulin julkinen ohjelmointirajapinta. Kaikki muut tiedoston paikalliset muuttujat ovat yksityisiä.

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

Yksityinen tila

Moduulitiedostossa local-määritteellä ilmoitetut muuttujat ovat yksityisiä – kutsujat eivät voi käyttää niitä. Moduulin funktiot voivat käyttää yksityistä tilaa upvalue-muuttujina. Tämä on Luan kapselointimekanismi.

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

Alustettava moduuli

Jotkin moduulit tarvitsevat alustuksen (määritykset, yhteydet). Sijoittakaa alustus koodina moduulin tasolle (tiedoston alkuun) tai erilliseen M.init()-funktioon. Moduulin tasolla oleva alustus suoritetaan kerran ensimmäisen require-kutsun yhteydessä, kun taas init() vaatii erillisen kutsun.

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

Luokan sisältävä moduuli

Moduuli voi viedä luokan: taulukon, jossa on konstruktorifunktio. Palautettu moduulitaulukko sisältää funktion new() ja voi toimia myös luokan metataulukkona.

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

Moduulivakiot

Viekää vakiot lisäämällä ne moduulitaulukkoon. Käytännön mukaan vakiot kirjoitetaan suuraakkosin. Koska Luassa ei ole const-määrettä, käyttäjät voivat teknisesti muuttaa niitä, mutta suuraakkoset ilmaisevat, että arvoa ei pidä muuttaa.

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

Moduulien versiointi

Sisällyttäkää moduuliin versiotieto. Kutsujat voivat tarkistaa version yhteensopivuuden varmistamiseksi. Käyttäkää semanttista versiointia (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"))

Alimoduulit

Suuret kirjastot jaetaan alimoduuleihin. Päämoduuli voi vaatia alimoduuleja ja viedä ne uudelleen, tai kutakin alimoduulia voidaan käyttää itsenäisesti. Järjestäkää tiedostot hakemistoihin, jotka vastaavat moduulipolkua.

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

Metataulukon sisältävä moduuli

Tehkää moduulista kutsuttava antamalla sille metataulukko, jossa on __call. Tämä on hyödyllistä moduuleille, jotka ovat ensisijaisesti funktioita mutta sisältävät myös apuohjelmia – päätoiminto on kutsu ja apuohjelmat ovat kenttiä.

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

Alimoduulien laiska lataus

Käyttäkää __index-metametodia alimoduulien lataamiseen laiskasti – moduulit ladataan vasta, kun niitä käytetään ensimmäisen kerran. Tämä nopeuttaa käynnistystä suurissa kirjastoissa, joissa on paljon alimoduuleja.

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

Moduulien testaamisen malli

Lisätkää moduulitiedoston loppuun testifunktio tai -lohko, joka suoritetaan ehdollisesti vain, kun tiedosto suoritetaan suoraan (eikä sitä ladata require-kutsulla). Näin yksikkötestit pysyvät koodin yhteydessä.

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

Pikatarkistus

Mikä on vakiotapa määrittää yksityinen tila Lua-moduulissa?

Kertaus: moduulien kirjoittaminen

Yhteenveto:

  • Malli: local M = {} ... return M
  • Tiedoston paikalliset muuttujat = yksityisiä; M:n kentät = julkinen ohjelmointirajapinta
  • Moduulitason koodi suoritetaan kerran ensimmäisen require-kutsun yhteydessä
  • Viekää luokat moduulitaulukossa olevan konstruktorin kautta
  • Ladatkaa alimoduulit laiskasti __index-metametodin avulla
  • Sisällyttäkää _VERSION yhteensopivuustarkistuksia varten
Aloita maksutta

Opi Lua tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
40
Oppitunnit
159

Usein kysytyt kysymykset

Onko oppitunti ”Moduulitiedoston kirjoittaminen” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Lua Academy-oppimispolun 3 oppituntia, myös oppitunnin “Moduulitiedoston kirjoittaminen”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Lua Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Moduulitiedoston kirjoittaminen”?

Luokaa moduuli palauttamalla funktioiden taulukko .lua-tiedostosta. Harjoittelet Lua Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Lua Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Lua Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.

Kuinka kauan ”Moduulitiedoston kirjoittaminen”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Lua Academy-oppitunnilla?

Kyllä. Jokainen Lua Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. require-funktio
  2. Moduulitiedoston kirjoittaminen
  3. package.path ja package.cpath
  4. Moduulien rakenteet ja parhaat käytännöt
← Takaisin: Lua Academy