Kirjautuminen

Haku

Tehtävät

Joulukalenteri 2009: Lua

Kirjoittaja: map_ (09.12.2009)

Esittely

Lua on vuonna 1993 Brasiliassa kehitetty skriptikieli, joka on tullut suosituksi erityisesti peliohjelmoijien keskuudessa. Kieli on yksinkertainen, kevyt ja helposti sulautettavissa: Lua-funktioita on helppoa kutsua esim. C++:sta ja päinvastoin.

Luan ainoa tietorakenne on taulu (table), jota voidaan indeksoida sekä luvuilla että merkkijonoilla. Jokaiselle taululle voidaan asettaa metataulu, jossa voidaan määritellä taululle erityistoiminnallisuutta. Metatauluun voidaan esimerkiksi kirjoittaa funktio, jota kutsutaan, kun taulua yritetään indeksoida avaimella, jota taulussa ei ole.

Kielessä ei varsinaisesti ole valmiita mekanismeja olio-ohjelmointiin, vaan oliot ja perintä toteutetaan tauluilla ja metatauluilla. Luaan on tapana luoda oliojärjestelmiä, jotka käyttävät perinteisten luokkien sijaan prototyyppiperintää ja ovat siten lähellä Javascriptin oliomallia.

Esimerkki: Tekstin tulostus

print("Valoisia jouluöitä!")

Esimerkki: Fibonaccin luvut

Seuraava ohjelma tulostaa Fibonaccin luvut, jotka ovat alle 100:

a = 0
b = 1
while (a < 100) do
  print(a)
  c = a + b
  a = b
  b = c
end

Esimerkki: Prototyyppiolioita ja operaattoriylikuormitusta

Tässä näytetään eräs tapa toteuttaa olio-ohjelmointi Luassa. Esimerkki on hieman yksinkertaistettu. Siinä kirjoitetaan asioita auki enemmän kuin on tarvis, eikä se toimi luontevasti perinnän kanssa, mutta idea on sama kuin "oikeassa" toteutuksessa.

Vector = { -- Luodaan prototyyppiolio (joka on taulu).
  x = 0,
  y = 0,
  tulosta = function (self)
    print("(" .. self.x .. ", " .. self.y .. ")")
  end
}

-- Luodaan metataulu, joka on tavallinen taulu erikoisroolissa.
-- Kun tämä taulu asetetaan jonkin muun taulun x metatauluksi,
-- ja ohjelmoija pyytää x:n tuntematonta jäsenta a
-- esimerkiksi kirjoittamalla x.a, jäsentä etsitään metataulun
-- __index-jäsenen osoittamasta paikasta.
Vector_meta = {
  __index = Vector
}

-- Seuraava funktio luo uusia Vector-instansseja
function createVector()
  local v = {}             -- Instanssit, kuten kaikki Lua-oliot, ovat tauluja

  -- Asetetaan instanssin metatauluksi Vector_meta.
  -- Nyt esim. v.x ja v.tulosta haetaan Vector-taulusta,
  -- koska v:ssä ei ole määritelty niitä suoraan.
  setmetatable(v, Vector_meta)

  return v
end

v1 = createVector()
v2 = createVector()

print(v1.x)  -- Tulostaa 0, joka tulee Vector-prototyypin oletusarvosta.

v1.x = 3
v2.y = 4

v1.tulosta(v1)  -- Tulostaa (3, 0)
v2:tulosta()    -- Tulostaa (0, 4).
                -- (Kaksoispiste tarkoittaa implisiittistä self-parametria.)

-- Laajennetaan Vector-metataulua operaattoriylikuormituksella

function Vector_meta.__add(a, b)
  local tulos = createVector()
  tulos.x = a.x + b.x
  tulos.y = a.y + b.y
  return tulos
end

-- Nyt kaikkia vektoreita voidaan laskea yhteen +-operaattorilla.

(v1 + v2):tulosta()  -- Tulostaa (3, 4)

Hauska tietää

Lua on World of Warcraftin, Crysisin, Grim Fandangon ja monen muun pelin skriptikieli.

Linkkejä

Tietoa sivustosta