*簡潔なクラス表記を実現する [#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 }}