-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoo.lua
104 lines (86 loc) · 2.04 KB
/
oo.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
local oo = {}
-- Basic instantiable classes, no inheritance.
local alloc = {}
function alloc:__call(...)
local obj = {}
self.init(obj, ...)
setmetatable(obj, self)
return obj
end
function defaultInit(self, args)
assert(args == nil, "Non-empty default args, probably bad")
end
function tostringWrapper(self)
return tostring(self:tostring())
end
function defaultTostring(self)
return self.class_name
end
function oo.Class(class_name)
local class = {}
class.__index = class
class.__tostring = tostringWrapper
class.init = defaultInit
class.tostring = defaultTostring
class.class_name = class_name or "(unnamed Class)"
setmetatable(class, alloc)
return class
end
-- Prototype objects. Calling a prototype creates a child instance.
local function copy(parent, child)
child.__index = child
child.__call = copy
return setmetatable(child, parent)
end
local copier = {}
copier.__call = copy
function oo.Prototype(base)
local proto = base or {}
proto.__index = proto
proto.__call = copy
return setmetatable(proto, copier)
end
-- Unit test
local Foo = oo.Class("Foo")
function Foo:hello()
return "hello"
end
function Foo:add1(n)
return n + 1
end
local foo = Foo()
assert(foo:hello() == "hello")
assert(foo:add1(2) == 3)
assert(tostring(foo) == "Foo")
local Bar = oo.Class()
function Bar:init(n)
self.value = n or 0
end
function Bar:inc()
self.value = self.value + 1
return self.value
end
function Bar:tostring()
return "Bar(" .. self.value .. ")"
end
local bar1 = Bar()
local bar2 = Bar(10)
assert(bar1:inc() == 1)
assert(bar1:inc() == 2)
assert(tostring(bar1) == "Bar(2)")
assert(bar2:inc() == 11)
assert(bar2:inc() == 12)
assert(tostring(bar2) == "Bar(12)")
local Hat = oo.Prototype {
name = "hat",
desc = function(self)
return self.colour .. " " .. self.name
end
}
local RedHat = Hat { colour = "red" }
local BlueHat = Hat { colour = "blue" }
local RedBowler = RedHat { name = "bowler" }
assert(RedHat:desc() == "red hat")
assert(BlueHat:desc() == "blue hat")
assert(RedBowler:desc() == "red bowler")
return oo