bebraw
8/30/2010 - 7:09 PM

account.lua

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)
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
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
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
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()
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)
    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 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
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