Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --------------------------------------------------------------------------
- -- minimal class system for lua
- -- features:
- -- * single/pseudo-multiple inheritance
- -- * fast, no functions involved in field/method dispatch
- -- * absolutely zero hand-holding :)
- -- * python-ish syntax:
- --
- -- local YourClass = class.YourClassName(superclass1,superclass2...)
- --
- -- class names are intentionally polluting global namespace
- -- to prevent name conflicts, cache into local if you're creating
- -- lots of instances.
- --
- -- superclasses can be just tables with fields you wish to have included
- -- in your class (ie mixins, unless you call super constructor)
- --
- -- examples:
- --
- -- class.ClassA {
- -- staticfield1=1,
- -- staticfield2=2,
- -- method=function(self,blah)
- -- -- methods can be defined like this, too
- -- end
- -- }
- -- function ClassA:new(arg,arg2)
- -- self.arg = arg
- -- self.arg2 = arg2
- -- -- self is prepared instance with static fields from superclasses
- -- end
- --
- -- instance = ClassA(arg,arg2) -- invoke class to get instance (calls :new)
- --
- -- inheritance:
- -- class.ClassB(ClassA, {
- -- staticfield1=3 -- this field will be overshadowed by ClassA!
- -- })
- -- function ClassB:new(arg,arg2)
- -- ClassA.new(self,arg,arg2) -- optionally call superclass
- -- end
- -- ClassB.staticfield2=3 -- this field will override superclasses
- --
- -- "multiple" inheritance:
- --
- -- class.ClassC()
- -- class.ClassD(ClassB,ClassC)
- -- function ClassD:new(arg1,arg2)
- -- ClassB.new(self,arg1,arg2) -- which super calls to include is up to you of course :)
- -- ClassC.new(self,arg1,arg2)
- -- end
- --
- -- --sd
- -- recursively walk list of mixin classes and patch em into the target class
- local function addsupers(target,supers)
- for i=1,#supers do -- faster than ipairs
- local super = supers[i]
- for k,v in pairs(super) do
- if not target[k] then
- target[k] = v
- end
- end
- addsupers(target, super.supers or {})
- end
- end
- -- create new instance
- local function instantiate(tk,...)
- local instance={}
- setmetatable(instance,tk.classmeta)
- return instance:new(...) or instance
- end
- -- superclasses are patched into our class metatable. we're trading speed for correctness,
- -- but it's usually safe to assume superclasses are final just before first object instance
- local function fix_supers(tk,...)
- tk.__call = instantiate
- addsupers(tk,tk.supers)
- return instantiate(tk,...)
- end
- class = setmetatable({}, {
- __index = function(klstab,kls)
- if rawget(_G, kls) then
- error("There is already '"..kls.."' in the global namespace!")
- end
- return function(...)
- local meta = {}
- local supers = {...}
- meta.classmeta = {__index=meta} -- this is the actual metatable for instances
- meta.class = kls -- class name, just for reference
- meta.supers = supers -- list of superclasses
- meta.__index = supers[1]
- meta.__call = fix_supers
- rawset(_G, kls, setmetatable(meta, meta))
- return meta
- end
- end
- })
- return class
Add Comment
Please, Sign In to add comment