Idiomy jsou konstrukce, které se neřeší logikou, ale naučením. Ty první číslované pochází z oficiální knihy Roberto Ierusalimschy: Programming in Lua, 4th edition.
x = x or value
Je obdobou zápisu if not x then x = value
Pokud hodnota x nemá hodnotu, přiřadí jí výchozí hodnotu value
. Nefunguje správně, pokud má x
hodnotu false
.
(a and b or c)
Případně ((a and b) or c)
Je obdobou klasické konstrukce s terciálním operátorem a ? b : c
který ale v Lua neexistuje. Nefunguje správně, pokud má b
hodnotu false
.
{ string.byte(s, 1, -1) }
Vytvoří seznam (tabulku) kódů všech znaků v s
. Funguje ale jen pro řetězce do cca 1MB, jinak dojde k přetečení zásobníku obsahujícího návratové hodnoty funkce. Definice je string,byte(s, start, end)
.
a[#a+1] = value
Funguje jen pro sekvence (sekvence = seznam položek 1..n bez děr, sequence = list 1..n without holes).
local f = assert(io.open(filename, mode))
Když IO funkce proběhne dobře, vrátí hodnotu a tu pošle dál i assert. Když IO funkce selže, vrátí dvě hodnoty: nil
, a textový popis chyby. Funkce assert
přijímá také dvě hodnoty, logickou hodnotu a text chyby. Při chybě nil
není vyhodnocen jako pravda, tak assert
vyvolá výjimku, jinak assert
vrátí výsledek IO funkce.
local a = a
Proběhne inicializace lokální proměnné a
hodnotou globální proměnné a
. Lokální proměnná a
začne být viditelná až po této deklaraci.
Následující jsou nečíslované, nejsou to již oficiálně proklamované idiomy, pouze konstrukce, které je nutné znát.
Pouze false
a nil
jsou v podmínkách vyhodnoceny jako false
. Vše ostatní je vyhodnoceno jako true
, včetně nuly a prázdného řetězce.
Ovšem pozor, ačkoliv podmínka vyhodnotí nil
jako false
, tak porovnání nikoliv nil == false
má hodnotu false
.
do
local x,y;
<do something>
end
Platnost dočasné proměnné omezíme blokem do .. end
.
local a,b = 1,2
Nelze použít jinde obvyklé: local a = 1, b = 2 -- CHYBA
Lua totiž nezná jinde obvyklý operátor čárka.
a,b = b,a
Lua provede korektně, protože se pravá strana vyhodnotí dřív než levá.
list = nil
list = { value = "something1", next = list }
list = { value = "something2", next = list }
...
Nově vložený prvek se stane začátkem (hlavou) seznamu a odkazuje na další prvek, který byl předchozí hlavou seznamu. Funguje dobře, protože se pravá stana vyhodnotila dříve než levá.
local f = function() f() end -- CHYBA
Volání f()
uvnitř funkce f()
zde volá globální funkci f()
(a pokud neexistuje globální f()
, tak volá nil
), protože deklarace lokální funkce f()
během zpracovávání jejího těla ještě neexistuje.
Lze vyřešit takto:
local f;
f = function() f() end -- SPRÁVNĚ
Lua se snaží problém obejít přes syntactic sugar, následující definice proběhne v pořádku:
local function f() f() end -- SPRÁVNĚ
Lua totiž interně zápis local function
rozvine a provede deklaraci jména funkce předem jako v příkladu výše.
I tak problém trvá, pokud se odkazujeme na lokální f()
z jiné funkce, která je v kódu deklarovaná dříve než f()
. Pokud nechceme skončit tak, že budeme deklarovat funkce povinně v pořadí, jak se na sebe odkazují, je snazší si napřed zadefinovat všechny jejich lokální identifikátory local f, g, h;
a pak teprve funkce deklarovat v libovolném pořadí.
Volání funkce nemusí používat závorky, pokud má funkce jeden argument, kterým je řetězec nebo table constructor.
print "a"
je totéž jak print("a")
type{}
je totéž jak type({})
f{x=10}
je totéž jak f({x=10})
Používá se k tvorbě pojmenovaných argumentů funkce foo{a=1, b=2}
je volání funkce s konstruktorem tabulky jako argumentem, uvnitř funkce foo(arg)
se používají zápisem arg.a
, arg.b
.
Může být matoucí, jelikož print "a"
funguje, ale print 1
je chyba. A print "a", "b"
znamená print("a"), "b"
, tedy vytiskne "a"
a vrátí nil, "b"
jako dva parametry.
Sekvenci vyrobíme z řady argumentů obecně:
tabulka = {...}
Opačný směr zajistí unpack
, což použijeme, když chceme sekvenci před jako argument volání funkce:
print(unpack(tabulka))
function f()
return -- chyba, return musí být poslední příkaz bloku
<do something>
end
Ale s blokem zafunguje:
function f()
do return end
<do something>
end