luaの学習ノート
この間『Programming in Lua,2 Nd Edition』を見て、いくつかのコードを記録しました.
local function languageTest()
-- table test
local names = {"Peter", "Paul", "Mary"}
local grades = {Mary=10, Paul=7, Peter=8}
table.sort(names, function(n1, n2)
return grades[n1] > grades[n2]
end)
for i=1, #names do
print(names[i])
end
-- function test
local function newCounter(name)
local i = 0
return function()
i = i+1
return name .. ":" .. i
end
end
local c1 = newCounter("c1")
local c2 = newCounter("c2")
print(c1())
print(c1())
print(c2())
print(c1())
print(c2())
-- for test
local function values(t)
local i = 0;
return function() i=i+1; return t[i] end
end
for elm in values(names) do
print(elm)
end
-- -- for test2
-- for k in pairs(names) do
-- print(k)
-- end
end
local function tableTest()
local Set = {}
local mt = {}
-- create a new set with teh values of the given list
Set.new = function(l)
local set = {}
setmetatable(set, mt)
for _, v in ipairs(l) do set[v] = true end
return set;
end
Set.union = function(a, b)
if getmetatable(a) ~= mt or getmetatable(b) ~= mt then
error("attempt to 'add' a set with a non-set value", 2);
end
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
Set.intersection = function(a, b)
local res = Set.new {}
for k in pairs(a) do
res[k] = b[k]
end
return res
end
Set.tostring = function(set)
local l = {}
for e in pairs(set) do
l[#l+1] = e
end
return "{" .. table.concat(l, ", ") .. "}"
end
Set.print = function(s)
print(Set.tostring(s))
end
mt.__add = Set.union
mt.__mul = Set.intersection
mt.__tostring = Set.tostring
mt.__le = function(a, b)
for k in pairs(a) do
if not b[k] then return false end
end
return true
end
mt.__lt = function(a, b)
return a<=b and not (b<=a)
end
mt.__eq = function(a, b)
return a<=b and b<=a
end
local s1 = Set.new {10, 20, 30, 50}
local s2 = Set.new {30, 1}
local s3 = s1+s2+s2
-- local s3 = s1+s2+s2 + 8
Set.print(s3)
Set.print((s1+s2)*s1)
s1 = Set.new{2, 4}
s2 = Set.new{4, 10, 2}
print(s1<=s2)
print(s1<s2)
print(s1>=s2)
print(s1>s2)
print(s1==s2*s1)
s1 = Set.new {10, 4, 5}
print(s1)
-- mt.__metatable = "not your business"
-- print(getmetatable(s1))
-- setmetatable(s1, {})
local Window = {} -- create a namespace
--create teh prototype with default values.
Window.prototype = {x=0, y=0, width=100, height=100}
Window.mt = {} -- create a metatable
--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.x)
-- Tables with default values
local function setDefault(t, d)
local mt = {__index = function() return d end}
setmetatable(t, mt)
end
local tab = {x=10, y=20}
print(tab.x, tab.z)
setDefault(tab, 0)
print(tab.x, tab.z)
local mt = {__index = function(t) return t.___ end }
local function setDefault(t, d)
t.___ = d
setmetatable(t, mt)
end
-- Tracking table accesses
local t = {} -- original table (created somewhere)
-- keep a private access to the 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]
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"
print(t[2])
-- Read-only tables
function readOnly(t)
local proxy = {}
local mt = {
__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])
-- days[2] = "Noday"
end
local function objectTest()
local Account = {
balance = 0,
new = function(self, o)
o = o or {} -- create table is user does not provide one
setmetatable(o, self)
self.__index = self
return o
end,
withdraw = function(self, v)
if v>self.balance then error"insufficient funds" end
self.balance = self.balance - v
end,
deposit = function(self, v)
self.balance = self.balance + v
end
}
local a = Account:new {balance = 0}
a:deposit(100.00)
print(a.balance)
local b = Account:new()
print(b.balance)
b.balance = 123
print(b.balance)
b:withdraw(100)
print(b.balance)
print(a.balance)
-- inheritance
local SpecialAccount = Account:new({
withdraw = function(self, v)
if v - self.balance >= self:getLimit() then
error"insufficient funds"
end
self.balance = self.balance - v
end,
getLimit = function(self)
return self.limit or 0
end
})
local s = SpecialAccount:new {limit=1000.00}
s:deposit(100.00)
s:withdraw(200.00)
print("s:", s.balance)
end
local function main()
languageTest();
tableTest();
objectTest();
end
main()