lua-users home
lua-l archive

[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.