- 追加された行はこの色です。
- 削除された行はこの色です。
*簡潔なクラス表記を実現する [#ja8ae593]
&aname(lua-class-lib);
** 以下を「cls.lua」などとしてファイルに保存。 [#d0d5e56b]
#sh(lua){{
-----------------------------------------------------------------------------
-- Lua Class Lib
--
-- Author: Robert Ray <louirobert@gmail.com> @ 2011
-- Home Page: http://code.google.com/p/lua-class-lib/
-- Licence: MIT
-- Version: 0.12
-- Note: See home page for document and update!
-----------------------------------------------------------------------------
module(..., package.seeall)
local function parseName(str)
local _begin, _end, cls = assert(str:find('%s*([a-zA-Z][a-zA-Z0-9_]*)%s*%:?'))
if not str:find(':', _end) then
return cls, {}
end
local bases = {}
while true do
local base
_begin, _end, base = str:find('%s*([a-zA-Z][a-zA-Z0-9_]*)%s*%,?', _end + 1)
if base then
table.insert(bases, base)
else
break
end
end
return cls, bases
end
local function create(t, ...)
local o = {}
if t.__init__ then
t.__init__(o, ...)
end
return setmetatable(o, {__index = t, __class__ = t})
end
function class(name)
local env = getfenv(2)
local clsName, bases = parseName(name)
for i, v in ipairs(bases) do
bases[i] = assert(env[v]) --Replace string name with class table
end
return function (t)
local meta = {__call = create, __bases__ = bases}
meta.__index = function(nouse, key)
for _, cls in ipairs(meta.__bases__) do
local val = cls[key] --Do a recursive search on each cls
if val ~= nil then
return val
end
end
end
local clsobj = setmetatable(t, meta)
env[clsName] = clsobj
return clsobj
end
end
function getClass(o)
local meta = assert(getmetatable(o))
return meta.__class__
end
function getBaseClasses(c)
local meta = assert(getmetatable(c))
return meta.__bases__
end
local function upTraverse(cls)
coroutine.yield(cls)
local bases = getmetatable(cls).__bases__
for _, v in ipairs(bases) do
upTraverse(v)
end
end
function upClasses(cls)
return coroutine.wrap(function() upTraverse(cls) end)
end
function isInstanceOf(o, c)
local cls = assert(getClass(o))
for one in upClasses(cls) do
if one == c then
return true
end
end
return false
end
_G.class = class
_G.isInstanceOf = isInstanceOf
}}
&aname(class-def);
**クラスの定義方法 [#l5258014]
#sh(lua){{
require 'cls'
module(..., package.seeall)
class 'Person'
{
__init__ = function(self, name)
self.name = name
end;
say = function(self)
print('Hello, my name is ' .. self.name .. '.')
self:saySthElse()
end;
saySthElse = function(self)
end
}
class 'Worker'
{
__init__ = function(self, id)
self.id = id
end;
showId = function(self)
print('My worker id is ' .. self.id .. '.')
end
}
class 'Employee: Person, Worker'
{
__init__ = function(self, name, salary, id)
Person.__init__(self, name)
Worker.__init__(self, id)
self.salary = salary
end;
saySthElse = function(self)
print('My salary is ' .. self.salary .. '.')
end
}
}}
&aname(class-use);
**定義したクラスの使用方法 [#uf15161c]
#sh(lua){{
require 'cls_demos'
print '--------------------------------------------'
p = cls_demos.Person('Bob')
p:say()
p2 = cls_demos.Person('David')
p2:say()
print '--------------------------------------------'
e = cls_demos.Employee('Bob', 1000, 1)
e:say()
e:showId()
e2 = cls_demos.Employee('Alice', 10000, 2)
e2:say()
e2:showId()
print '--------------------------------------------'
if isInstanceOf(e, cls_demos.Person) then
print 'e is an instance of Person'
else
print 'e is not an instance of Person'
end
if isInstanceOf(e, cls_demos.Worker) then
print 'e is an instance of Worker'
else
print 'e is not an instance of Worker'
end
w = cls_demos.Worker(100)
if isInstanceOf(w, cls_demos.Person) then
print 'w is an instance of Person'
else
print 'w is not an instance of Person'
end
if isInstanceOf(w, cls_demos.Worker) then
print 'w is an instance of Worker'
else
print 'w is not an instance of Worker'
end
}}