lua-users home
lua-l archive

Pure Lua class

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi, all!
After reading on http://www.lua.org/notes/ articles
* LTN 7 - Modules & packages, by Roberto Ierusalimschy
* LTN 8 - A fast multiple-inheritance tag method implementation in Lua, by David Jeske,
I try merge in one simple script two ideas:
 - make 'flat object' in the constructor
 - implement private fields and methods via upvalues
I think, it's may be interesting for somebody.
-- class.lua
-- simple-inherited class with static, public and private vars and funcs for 
lua 4.0
function class(c) -- create the class and it`s constructor
 if c._tag==nil then c._tag=newtag() end
 c.new = function(self,t) -- t - table
 local o, super = {},self._super
 local k, v
 local proto = {}
 if type(super)=="table" then o = super:new() end
 -- save "prototype of the instance",
 -- for access from _init() to overloaded functions
 for k,v in o do
 -- you can add where more assertions
 if type(v)=="function" then proto[k]=v end
 end
 -- extend or clone
 if type(self._public)=="table" then
 for k,v in self._public do o[k] = v end
 end
 o._class = self
 -- user defined initialization
 if type(self._init)=="function" then
 self._init(o,t,proto)
 elseif type(t)=="table" then -- default initialization
 for k,v in t do if o[k] then o[k]=v end end
 end
 settag(o,self._tag)
 return o
 end
 return c
end
-- test
-- base class (superclass)
A = class{ _public={ a=1, 
 f=function(self) return "A.f()->self.a="..self.a end
 } 
}
-- derived class (subclass)
B = class{ _super=A, 
 staticvar=2,
 _public = {
 b=3, 
 h=function(self) return "B.h()->"..(self.a self.b) end,
 },
 _init = function(self,t,proto) -- init instance of class
 local p={c=4} -- private vars
 local k,v
 local privfunc = function(self) return self.a self.b %p.c end
 local A_f=proto.f -- for access from redefined method
 -- define public funcs which need access to private vars&funcs
 self.g = function(self) return "B.g()->"..%privfunc(self) end
 self.setc = function(self,value) %p.c=value end
 self.f = function(self) return %A_f(self).." B.f()->self.b="..self.b 
end 
 for k,v in t do -- init public and private members
 if self[k] then self[k]=v
 elseif p[k] then p[k]=v
 end
 end
 end,
}
--
a=A:new()
b=B:new{a=10, c=20}
print("a.f()=", a:f())
print("b:f(), b:g(), b:h()", b:f(), b:g(), b:h())
-- yet another way call method from super class
-- only "static" or from _public table
print( "b._class._super._public.f(b)=",b._class._super._public.f(b))
b:setc(1) -- set private field c
print("b:g() = ",b:g())
print("b._class.staticvar=",b._class.staticvar)
--- end of class.lua
Drawbacks:
- I don't know as implement 'protected' fields and methods (it's possible?)
- it model don't work with multi-inheritance classes. Constuctor create 'flat' 
obect-table and last 
field/method will overload all fields/methods with same name from previous 
parent classes.
Best regards.
Vladimir D.

AltStyle によって変換されたページ (->オリジナル) /