-------------------------
-- tables are general container can be indexed by anything (numbers,
-- tables, strings, functions...)
local function blah()
print("blah")
end
tab[blah] = blubb
tab.name = blubb -- is same as
tab["name"] = blubb
-- tables are always passed as "pointers/references" never copied
-- array index starts with 1 !!
-- they become garbage collected when not referenced anymore
pos = {1,2,3}
a = { pos = pos }
pos[3] = 4
pos = {1,1,1} -- overwrites local variable pos
a.pos[3] -- is still 4
-------------------------
--[[ multiline
comment ]]
blah = [==[ multiline string and comment
can use multiple = for bracketing to nest ]==]
-------------------------
--- multiple return values allow easy swapping
a,b = b,a
-------------------------
-- object oriented stuff
-- : operator passes first arg
a.func(a,blah) -- is same as
a:func(blah)
-- metatables allow to index class tables
myclass = {}
myclassmeta = {__index = myclass}
function myclass:func()
self --automatic variable through : definiton for the first
--arg passed to func
end
-- above is equivalent to
myclass.func = function (self)
end
object = {}
setmetatable(object,myclassmeta)
object:func() -- is now same as
myclass.func(object)
-- until func gets specialized per object
function object:func()
-- lua will look up first in the object table, then in the metatable
-- it will ony write to the object table
end
-------------------------
--- upvalues for function specialization
function func(obj)
return function ()
return obj * 2
end
end
a = func(1)
b = func(2)
a() -- returns 2
b() -- returns 4
--- non passed function arguments become nil automatically
function func (a,b)
return a,b
end
a,b = func(1) -- b is "nil"
--- variable args
function func(...)
local a,b = ...
--- a,b would be first two args
--- you can also put args in a table
local t = {...}
end
-------------------------
--- conditional assignment chaining
--- 0 is not "false", only "false" or "nil" are
a = 0
b = a or 1 -- b is 0, if a was false/nil it would be 1
c = (a == 0) and b or 2 -- c is 0 (b's value)
-- the first time a value is "valid" (non-false/nil) that value is taken
-- that way you can do default values
function func(a,b)
a = a or 1
b = b or 1
end
-------------------------
--- sandboxing
function sandboxedfunc()
-- after setfenv below we can only call what is enabled in the enviroment
-- so in the example below doing stuff like io.open wouldn't work here
-- blubb becomes created in the current enviornment
blubb = doit()
end
local enva = {
doit = function () return 1 end
}
local envb = {
doit = function () return 2 end
}
setfenv(sandboxedfunc,enva)()
--enva.blubb is now 1
setfenv(sandboxedfunc,envb)()
--envb.blubb is now 2
-- sandboxedfunc could also come from a file, which makes creating fileformats
-- quite easy, as they can internally be lua code
-------------------------
--- functions without () and function chaining
-- to make ini/config files quite easy, lua allows omitting () for function
-- calls when the argument is either a string or a table
function testfunc( a )
end
-- valid calls to above function
testfunc "blah"
testfunc {1,2,3}
-- we can even expand this to create fileformat like structures
function group( name)
return function (content)
local grp = {
name = name,
content = content,
}
return grp
end
end
local grp = group "test" {1,3,5}
-- equvialent to: group("test")({1,3,5})
-- grp.content[2] = would be 3
-- could also build a hierarchy
local grp = group "root" {
group "child a" {},
group "child b" {},
}
-- grp.content[1].name would be "child a"