print(a)
--[[
print(10) -- no action (comment)
--]]
---[[
print(10) --> 10
--]]
The number type represents real (double-precision floating-point) numbers. Lua has no integer type, as it does not need it.
a.name
a["name"]
1 ~= 2
and -- &&
or -- ||
not -- !
print("Hello " .. "World") --> Hello World
print(0 .. 1) --> 01
a = {x=0, y=0}
a = {}; a.x=0; a.y=0
polyline = {color="blue", thickness=2, npoints=4,
{x=0, y=0}, -- [1]
{x=-10, y=0}, -- [2]
{x=-10, y=1}, -- [3]
{x=0, y=1} -- [4]
}
print(polyline[2].x) --> -10
print(polyline[3].y) --> 1
a, b = 10, 2*x
x, y = y, x -- swap `x' for `y'
a[i], a[j] = a[j], a[i] -- swap `a[i]' for `a[j]'
a, b, c = 0, 1
print(a,b,c) --> 0 1 nil
j = 10 -- global variable
local i = 1 -- local variable
local foo = foo
do
local a2 = 2*a
local d = sqrt(b^2 - 4*a*c)
x1 = (-b + d)/a2
x2 = (-b - d)/a2
end -- scope of `a2' and `d' ends here
print(x1, x2)
if op == "+" then
r = a + b
elseif op == "-" then
r = a - b
elseif op == "*" then
r = a*b
elseif op == "/" then
r = a/b
else
error("invalid operation")
end
local i = 1
while a[i] do
print(a[i])
i = i + 1
end
-- print the first non-empty line
repeat
line = os.read()
until line ~= ""
print(line)
for i=1,f(x) do print(i) end
for i=10,1,-1 do print(i) end -- -1은 step. 생략하면 1이 디폴트
-- print all values of array `a'
for i,v in ipairs(a) do print(v) end
-- print all keys of table `t'
for k in pairs(t) do print(k) end
local i = 1
while a[i] do
if a[i] == v then break end
i = i + 1
end
function foo2 () return 'a','b' end -- returns 2 results
x,y = foo2() -- x='a', y='b'
x = foo2() -- x='a', 'b' is discarded
x,y,z = 10,foo2() -- x=10, y='a', z='b'
a = {foo2()} -- a = {'a', 'b'}
print(unpack{10,20,30}) --> 10 20 30
a,b = unpack{10,20,30} -- a=10, b=20, 30 is discarded
print(unpack{a = 10, b= 20, c = 30}) --> 아무것도 안 나와. 숫자 인덱스만 가능
print(string.find("hello hello", " hel")) --> 6 9
printResult = ""
function printConcat (...)
for i,v in ipairs(arg) do
printResult = printResult .. tostring(v) .. "\t"
end
printResult = printResult .. "\n"
end
printConcat(2, 5, 1, "aaww", "test")
print(printResult)
local _, x = string.find("hello hello", " hel") --> _:6 x:9
print(x) --> 9
function selecting (n, ...)
return arg[n]
end
print(selecting(1, string.find("hello hello", " hel"))) --> 6
function fwrite (fmt, ...)
return io.write(string.format(fmt, unpack(arg)))
end
function rename (arg)
print("old - "..arg.old..", new - "..arg.new)
end
rename{old="temp.lua", new="temp1.lua"}
rename{old="temp.lua", new="temp1.lua"}
rename({old="temp.lua", new="temp1.lua"})
When a function is written enclosed in another function, it has full access to local variables from the enclosing function
function sortbygrade (names, grades)
table.sort(names, function (n1, n2)
return grades[n1] > grades[n2] -- compare the grades
end)
end
function newCounter ()
local i = 0
return function () -- anonymous function
i = i + 1
return i
end
end
c1 = newCounter()
print(c1()) --> 1
print(c1()) --> 2
c2 = newCounter()
print(c2()) --> 1
print(c1()) --> 3
print(c2()) --> 2
function digitButton (digit)
return Button
{
label = digit,
action = function ()
add_to_display(digit)
end
}
end
do
local oldSin = math.sin
local k = math.pi/180
math.sin = function (x)
return oldSin(x*k)
end
end
do
local oldOpen = io.open
io.open = function (filename, mode)
if access_OK(filename, mode) then
return oldOpen(filename, mode)
else
return nil, "access denied"
end
end
en
Lib = {}
Lib.foo = function (x,y) return x + y end
Lib.goo = function (x,y) return x - y end
-- or
Lib = {
foo = function (x,y) return x + y end,
goo = function (x,y) return x - y end
}
-- or
Lib = {}
function Lib.foo (x,y)
return x + y
end
function Lib.goo (x,y)
return x - y
end
local f = function (...)
...
end
-- or
local function f (...)
...
end
function foo (n)
if n > 0 then return foo(n - 1) end
end
function list_iter (t)
local i = 0
local n = table.getn(t)
return function ()
i = i + 1
if i <= n then return t[i] end
end
end
function list_iter (t)
local i = 0
local n = table.getn(t)
return function ()
i = i + 1
if i <= n then return t[i] end
end
end
t = {10, 20, 30}
iter = list_iter(t) -- creates the iterator
while true do
local element = iter() -- calls the iterator
if element == nil then break end
print(element)
end
t = {10, 20, 30}
for element in list_iter(t) do
print(element)
end
function iter (a, i)
i = i + 1
local v = a[i]
if v then
return i, v
end
end
function ipairs (a)
return iter, a, 0
end
a = {x = "one", y = "two", z = "three"}
function pairs (t)
return next, t, nil
end
for k, v in pairs(a) do
print(k, v)
end
for k, v in next, a do
print(k, v)
end
?;?.lua;c:\windows\?;/usr/local/lua/?/?.lua
lili
lili.lua
c:\windows\lili
/usr/local/lua/lili/lili.lua
co = coroutine.create(function ()
for i=1,3 do
print("co", i)
coroutine.yield()
end
end)
coroutine.resume(co) --> co 1
print(coroutine.status(co)) --> suspended
coroutine.resume(co) --> co 2
coroutine.resume(co) --> co 3
coroutine.resume(co) --> 아무일도 하지 않는다
print(coroutine.status(co)) --> dead
print(coroutine.resume(co)) --> false cannot resume dead coroutine
co = coroutine.create(function (a,b,c)
print("co", a,b,c)
end)
coroutine.resume(co, 1, 2, 3) --> co 1 2 3
co = coroutine.create (function ()
print("co", coroutine.yield())
end)
coroutine.resume(co)
coroutine.resume(co, 4, 5) --> co 4 5
co = coroutine.create(function ()
return 6, 7
end)
print(coroutine.resume(co)) --> true 6 7
co = coroutine.create(function (a,b)
coroutine.yield(a + b, a - b)
end)
print(coroutine.resume(co, 20, 10)) --> true 30 10
function receive (prod)
local status, value = coroutine.resume(prod)
return value
end
function send (x)
coroutine.yield(x)
end
function producer ()
return coroutine.create(function ()
while true do
local x = io.read() -- produce new value
send(x)
end
end)
end
function filter (prod)
return coroutine.create(function ()
local line = 1
while true do
local x = receive(prod) -- get new value
x = string.format("%5d %s", line, x)
send(x) -- send it to consumer
line = line + 1
end
end)
end
function consumer (prod)
while true do
local x = receive(prod) -- get new value
io.write(x, "\n") -- consume new value
end
end
consumer(filter(producer()))
function permgen (a, n)
if n == 0 then
coroutine.yield(a)
else
for i=1,n do
-- put i-th element as the last one
a[n], a[i] = a[i], a[n]
-- generate all permutations of the other elements
permgen(a, n - 1)
-- restore i-th element
a[n], a[i] = a[i], a[n]
end
end
end
function perm (a)
local n = table.getn(a)
return coroutine.wrap(function () permgen(a, n) end)
end
function printResult (a)
for i,v in ipairs(a) do
io.write(v, " ")
end
io.write("\n")
end
for p in perm{"a", "b", "c"} do
printResult(p)
end
a = {} -- new array
for i=1, 1000 do
a[i] = 0
end
local N = 10
local M = 10
mt = {} -- create the matrix
for i=1,N do
mt[i] = {} -- create a new row
for j=1,M do
mt[i][j] = 0
end
end
list = nil -- head
list = {next = list, value = "val"}
local l = list
while l do
print(l.value)
l = l.next
end
List = {}
function List.new ()
return {first = 0, last = -1}
end
function List.pushleft (list, value)
local first = list.first - 1
list.first = first
list[first] = value
end
function List.pushright (list, value)
local last = list.last + 1
list.last = last
list[last] = value
end
function List.popleft (list)
local first = list.first
if first > list.last then error("list is empty") end
local value = list[first]
list[first] = nil -- to allow garbage collection
list.first = first + 1
return value
end
function List.popright (list)
local last = list.last
if list.first > last then error("list is empty") end
local value = list[last]
list[last] = nil -- to allow garbage collection
list.last = last - 1
return value
end
reserved =
{
["while"] = true,
["end"] = true,
["function"] = true,
["local"] = true,
}
for w in allwords() do
if reserved[w] then
-- `w' is a reserved word
...
local t = {}
for line in io.lines() do
table.insert(t, line)
end
s = table.concat(t, "\n") .. "\n"
-- WARNING: bad code ahead!!
local buff = ""
for line in io.lines() do
buff = buff .. line .. "\n"
end
table은 못하는 테이블 추가, 비교, 호출을 할 수 있게 해준다
Set = {}
Set.mt = {} -- metatable for sets
function Set.new (t)
local set = {}
setmetatable(set, Set.mt)
for _, l in ipairs(t) do
set[l] = true
end
return set
end
function Set.union (a,b)
local res = Set.new{}
for k in pairs(a) do
res[k] = true
end
for k in pairs(b) do
res[k] = true
end
return res
end
s1 = Set.new{10, 20, 30, 50}
s2 = Set.new{30, 1}
assert(getmetatable(s1) == getmetatable(s2))
Set.mt.__add = Set.union -- metamethod를 추가
s3 = s1 + s2 --> {1, 30, 10, 50, 20}
Set.mt.__le = function (a,b)
for k in pairs(a) do
if not b[k] then return false end
end
return true
end
Set.mt.__lt = function (a,b)
return a <= b and not (b <= a)
end
Set.mt.__tostring = Set.tostring
s1 = Set.new{10, 4, 5}
print(s1) --> {4, 5, 10}
-- create a namespace
Window = {}
-- create the prototype with default values
Window.prototype = {x=0, y=0, width=100, height=100, }
-- create a metatable
Window.mt = {}
-- declare the constructor function
function Window.new (o)
setmetatable(o, Window.mt)
return o
end
--------------------------------------------------
Window.mt.__index = function (table, key)
return Window.prototype[key]
end
-- 이 예제에선 동작이 필요한 게 아니라
-- 그냥 테이블 할당이므로 이렇게 간단하게 적을 수 있다
-- Window.mt.__index = Window.prototype
--------------------------------------------------
w = Window.new{x=10, y=20}
print(w.width) --> 100
function setDefault (t, d)
local mt =
{
__index = function ()
return d
end
}
setmetatable(t, mt)
end
tab = {x=10, y=20}
print(tab.x, tab.z) --> 10 nil
setDefault(tab, 0)
print(tab.x, tab.z) --> 10 0
local mt =
{
__index = function(t)
return t.___
end
}
function set_default(t, d)
t.___ = d
setmetatable(t, mt)
end
tab_a = {}
tab_b = {}
set_default(tab_a, 0)
print(tab_a.no) --> 0
print(tab_b.no) --> nil
set_default(tab_b, 1)
print(tab_a.no) --> 0
print(tab_b.no) --> 1
local key = {} -- unique key
local mt = {__index = function (t) return t[key] end}
function setDefault (t, d)
t[key] = d
setmetatable(t, mt)
end
t = {} -- original table (created somewhere)
-- keep a private access to original table
local _t = t
-- create proxy
t = {}
-- create metatable
local mt =
{
__index = function (t,k)
print("*access to element " .. tostring(k))
return _t[k] -- access the original table
end,
__newindex = function (t,k,v)
print("*update of element " .. tostring(k) .. " to " .. tostring(v))
_t[k] = v -- update original table
end
}
setmetatable(t, mt)
t[2] = 'hello' --> *update of element 2 to hello
print(t[2]) --> *access to element 2
-- create private index
local index = {}
-- create metatable
local mt =
{
__index = function (t,k)
print("*access to element " .. tostring(k))
return t[index][k] -- access the original table
end,
__newindex = function (t,k,v)
print("*update of element " .. tostring(k) .. " to " .. tostring(v))
t[index][k] = v -- update original table
end
}
function track (t)
local proxy = {}
proxy[index] = t
setmetatable(proxy, mt)
return proxy
end
tab_1 = {}
tab_1 = track(tab_1)
tab_1[1] = 'hello'
print(tab_1[1])
tab_2 = {}
tab_2 = track(tab_2)
tab_2[1] = 'hello 2'
print(tab_2[1])
function readOnly (t)
local proxy = {}
local mt =
{ -- create metatable
__index = t,
__newindex = function (t,k,v)
error("attempt to update a read-only table", 2)
end
}
setmetatable(proxy, mt)
return proxy
end
days = readOnly{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
print(days[1]) --> Sunday
days[2] = "Noday" --> attempt to update a read-only table
complex = {}
function complex.new (r, i) return {r=r, i=i} end
-- defines a constant `i'
complex.i = complex.new(0, 1)
function complex.add (c1, c2)
return complex.new(c1.r + c2.r, c1.i + c2.i)
end
function complex.sub (c1, c2)
return complex.new(c1.r - c2.r, c1.i - c2.i)
end
function complex.mul (c1, c2)
return complex.new(c1.r*c2.r - c1.i*c2.i, c1.r*c2.i + c1.i*c2.r)
end
function complex.inv (c)
local n = c.r^2 + c.i^2
return complex.new(c.r/n, -c.i/n)
end
-- complex는 global variable. 그래서 return이 필요없어 보인다
-- 하지만 패키지를 열었을 때, 패키지를 리턴하는 게 좋다
-- 패키지를 사용하는 다른 방법을 제공하기 때문
-- good practice
return complex
local P = {}
complex = P -- package name
P.i = {r=0, i=1}
function P.new (r, i) return {r=r, i=i} end
function P.add (c1, c2)
return P.new(c1.r + c2.r, c1.i + c2.i)
end
-- ...
local P = {} -- package
if _REQUIREDNAME == nil then
complex = P
else
_G[_REQUIREDNAME] = P
end
local P = {}
complex = P
-- function environment를 변경. 1은 스택 레벨.
-- 즉 1은 현재 함수, 2는 현재 함수를 호출한 함수
setfenv(1, P)
function add (c1, c2)
return new(c1.r + c2.r, c1.i + c2.i)
end
local P = {}
pack = P
-- Import Section:
-- declare everything this package needs from outside
local sqrt = math.sqrt
local io = io
-- no more external access after this point
setfenv(1, P)
Account = { balance = 0 }
-- colon operator를 사용하면 첫번째 인자로 self를
-- lua에서 넘겨준다
function Account:withdraw (v)
self.balance = self.balance - v
end
a = Account
a:withdraw(100.00) -- lua에서 a를 self 패러매터 인자로 넘김
a.withdraw(a, 100.00) -- 명시적으로 a를 넘김
function Account:new (o)
o = o or {} -- create object if user does not provide one
setmetatable(o, self)
self.__index = self
return o
end
a = Account:new{balance = 0}
a:deposit(100.00) -- getmetatable(a).__index.deposit(a, 100.00)
SpecialAccount = Account:new()
function SpecialAccount:withdraw (v)
if v - self.balance >= self:getLimit() then
error"insufficient funds"
end
self.balance = self.balance - v
end
function SpecialAccount:getLimit ()
return self.limit or 0
end
function newAccount (initialBalance)
local self = {balance = initialBalance} -- 외부 노출 X
local withdraw = function (v)
self.balance = self.balance - v
end
local deposit = function (v)
self.balance = self.balance + v
end
local getBalance = function ()
return self.balance
end
return
{
withdraw = withdraw,
deposit = deposit,
getBalance = getBalance
}
end
function newObject (value)
return function (action, v)
if action == "get" then return value
elseif action == "set" then value = v
else error("invalid action") end
end
end
d = newObject(0)
print(d("get")) --> 0
d("set", 10)
print(d("get")) --> 10