Skip to content

Instantly share code, notes, and snippets.

@bebraw
Created August 30, 2010 19:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bebraw/557874 to your computer and use it in GitHub Desktop.
Save bebraw/557874 to your computer and use it in GitHub Desktop.
Account = {balance = 0, }
function Account:new (o)
o = o or {} -- create object if user does not provide one
setmetatable(o, self)
self.__index = self
return o
end
function Account:deposit (v)
self.balance = self.balance + v
end
function Account:withdraw (v)
if v > self.balance then error"insufficient funds" end
self.balance = self.balance - v
end
a = Account:new{balance = 0}
a:deposit(100.0)
b = Account:new()
print(b.balance) --> 0
b:deposit(50.0)
print(b.balance) --> 50.0
local authors = {} -- a set to collect authors
function Entry (b)
if b.author then authors[b.author] = true end
end
dofile("data")
for name in pairs(authors) do print(name) end
Entry{
author = "Donald E. Knuth",
title = "Literate Programming",
publisher = "CSLI",
year = 1992
}
Entry{
author = "Jon Bentley",
title = "More Programming Pearls",
publisher = "Addison-Wesley",
year = 1990
}
local key = {} -- unique key
local mt = {__index = function (t) return t[key] end}
function setDefault (t, d)
t[key] = d
setmetatable(t, mt)
end
tab = {x=10, y=20}
print(tab.x, tab.z)
setDefault(tab, 0)
print(tab.x, tab.z)
function room1 ()
local move = io.read()
if move == "south" then return room3()
elseif move == "east" then return room2()
else print("invalid move")
return room1() -- stay in the same room
end
end
function room2 ()
local move = io.read()
if move == "south" then return room4()
elseif move == "west" then return room1()
else print("invalid move")
return room2()
end
end
function room3 ()
local move = io.read()
if move == "north" then return room1()
elseif move == "east" then return room4()
else print("invalid move")
return room3()
end
end
function room4 ()
print("congratulations!")
end
room1()
require "specialaccount"
-- look up for 'k' in list of table 'plist'
local function search (k, plist)
for i=1, table.getn(plist) do
local v = plist[i][k] -- try 'i'-th superclass
if v then return v end
end
end
function createClass (...)
local c = {} -- new class
-- class will search for each method in list of its parent
-- ('arg' is the list of parent)
setmetatable(c, {__index = function (t, k)
local v = search(k, arg)
t[k] = v -- save for next access
return v
end})
-- prepare 'c' to be the metatable of its instances
c.__index = c
-- define a new constructor for this new class
function c:new (o)
o = o or {}
setmetatable(o, c)
return o
end
-- return new class
return c
end
Named = {}
function Named:getname ()
return self.name
end
function Named:setname (n)
self.name = n
end
NamedAccount = createClass(Account, Named)
s = SpecialAccount:new{limit=1000.00}
print(s.balance)
account = NamedAccount:new{name = "Paul"}
print(account.name)
account.name = "Jack"
account:setname("Bill")
print(account:getname()) --> Paul
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)
if getmetatable(a) ~= Set.mt or
getmetatable(b) ~= Set.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)
local res = Set.new{}
for k in pairs(a) do
res[k] = b[k]
end
return res
end
Set.mt.__le = function (a,b) -- set containment
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.__eq = function (a,b)
return a <= b and b <= a
end
function Set.tostring (set)
local s = "{"
local sep = ""
for e in pairs(set) do
s = s .. sep .. e
sep = ", "
end
return s .. "}"
end
function Set.print (s)
print(Set.tostring(s))
end
Set.mt.__add = Set.union
Set.mt.__mul = Set.intersection
Set.mt.__tostring = Set.tostring
s1 = Set.new{10, 20, 30, 50}
s2 = Set.new{30, 1}
print(getmetatable(s1))
print(getmetatable(s2))
s3 = s1 + s2
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 >= s1)
print(s1 > s1)
print(s1 == s2 * s1)
s1 = Set.new{10, 4, 5}
print(s1)
s = Set.new{1,2,3}
s = s + 8
Set = {}
Set.mt = {} -- metatable for sets
Set.mt.__metatable = "not your business"
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)
if getmetatable(a) ~= Set.mt or
getmetatable(b) ~= Set.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)
local res = Set.new{}
for k in pairs(a) do
res[k] = b[k]
end
return res
end
Set.mt.__le = function (a,b) -- set containment
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.__eq = function (a,b)
return a <= b and b <= a
end
function Set.tostring (set)
local s = "{"
local sep = ""
for e in pairs(set) do
s = s .. sep .. e
sep = ", "
end
return s .. "}"
end
function Set.print (s)
print(Set.tostring(s))
end
Set.mt.__add = Set.union
Set.mt.__mul = Set.intersection
Set.mt.__tostring = Set.tostring
s1 = Set.new{}
print(getmetatable(s1))
setmetatable(s1, {})
s1 = Set.new{10, 20, 30, 50}
s2 = Set.new{30, 1}
print(getmetatable(s1))
print(getmetatable(s2))
s3 = s1 + s2
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 >= s1)
print(s1 > s1)
print(s1 == s2 * s1)
s1 = Set.new{10, 4, 5}
print(s1)
s = Set.new{1,2,3}
s = s + 8
Account = {balance = 0}
function Account:new (o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function Account:deposit (v)
self.balance = self.balance + v
end
function Account:withdraw (v)
if v > self.balance then error"insufficient funds" end
self.balance = self.balance - v
end
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
s = SpecialAccount:new{limit=1000.00}
print(s.balance)
s:deposit(100.00)
print(s.balance)
s:withdraw(200.00)
print(s.balance)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment