20.1
#!/usr/bin/lua
local Set={}
local mt={}
function Set.new(l)
local set={}
setmetatable(set,mt)
for _,v in pairs(l) do
set[v]=true
end
return set
end
function Set.union(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
function Set.intersection(a,b)
if getmetatable(a)~=mt or getmetatable(b)~=mt then
error("attempt to 'multiply' a set with a non-set value",2)
end
local res=Set.new{}
for k in pairs(a) do
res[k]=b[k]
end
return res
end
function Set.subtraction(a,b)
if getmetatable(a)~=mt or getmetatable(b)~=mt then
error("attempt to 'subtract' 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]=nil
end
return res
end
function Set.tostring(set)
local l={}
for e in pairs(set) do
l[#l+1]=e
end
return "{"..table.concat(l,",").."}"
end
function Set.length(set)
local count=0
for i in pairs(set) do
count=count+1
end
return count
end
mt.__add=Set.union
mt.__mul=Set.intersection
mt.__sub=Set.subtraction
mt.__len=Set.length
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
return Set
for test
#!/usr/bin/lua
t=require("20-1and20-2")
a=t.new({1,2,3,4})
b=t.new{3,5}
print(a-b)
print(a+b)
print(a*b)
print("#a="..#a)
20.2
同上
20.3
#!/usr/bin/lua
local proxy={}
local mt={}
function readOnly(t)
mt.__index=function (_,k) return rawget(t,k) end
mt.__newindex=function (t,k,v) error("attempt to update a read-only table",2) end
setmetatable(proxy,mt)
return proxy
end
days={"Sunday","Monday","Tuesday","Wednesday","Tursday","Friday","Saturday"}
days=readOnly(days)
print(days[1])
days[2]="Noday"
20.4
#!/usr/bin/lua
function fileAsArray(filename)
local proxy={}
local filearray={}
local file=assert(io.open(filename,"r"))
for block in file:lines(1) do
filearray[#filearray+1]=block
end
file:close()
local mt={
__index=function (_,k) return filearray[k] end,
__newindex=function (_,k,v)
filearray[k]=v
local file=assert(io.open(filename,"w"))
for _,w in ipairs(filearray) do
file:write(w)
end
file:close()
end,
__pairs=function ()
return function (_,k)
local nextkey,nextvalue=next(filearray,k)
return nextkey,nextvalue
end
end,
__len=function ()
return #filearray
end
}
setmetatable(proxy,mt)
return proxy
end
--the content under the line are for test
f=fileAsArray("text")
print(f[2])
f[2]="i"
for x,y in pairs(f) do
print(x,y)
end
print(#f)
20.5
同上