lua-users home
lua-l archive

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


John Belmonte wrote:
> 
> If you have any code examples making use of this patch, it would be
> interesting to see them.

Here's an example for a simple class system.  It uses three aditional
minor patches to Lua:

1) An unpack function.  It takes a numeric table as an argument and
simply returns all its fields.

2) The ',' in constructors is optional.  Patch sent a few days ago.

3) It allows function definitions in constructors.  So, function name(...)
is the same as  name=function(...)

And here's the example.  Note that the class system never copies
data or functions around nor does it modify any data given.  It just
manages the creation of objects and the inheritance of class members.

Ciao, ET.

PS: This code is not used anywhere.  I just wrote it as an example.
So it may be buggy or not useful for real work *g*.  But I think it
could...
----- example for a simple class system using 'unified methods' -----

do
    -- default methods - inherited by all classes
    local default_methods = {
	-- the default allocator
	function alloc()
	  return {}
	end

	-- the default new
	function new(obj)
	  -- do nothing
	end

	-- access methods in upper classes
	function upper(obj, method, ...)
	  return obj:base[method](obj, unpack(arg))
	end

	-- show contents of object (will break on userdata)
	function show(obj, info)
	  print("contents of '"..obj:name..":"..(info or "???").."'")
	  foreach(obj, print)
	end
    }

    -- class methods - management of classes
    local class_methods = {
	-- calling a class creates a new instance
	function call(class, ...)
	  local obj = class.alloc(unpack(arg))
	  methods(obj, class)
	  obj:new(unpack(arg))
	  return obj
	end

	-- missing elements are taken from base class or default table
	function index(class, method)
	  local base = rawget(class, 'base') or %default_methods
	  return base[method] -- may invocate further 'index' methods
	end
    }

    function class(class_specs)
      methods(class_specs, %class_methods)
      return class_specs
    end

end

----- that's all -----


-- now some examples on how to use it

class1 = class {		-- start a new class definition
    name = "class1"		-- class name

    -- new is called to initialize a new object.  self is the new object.
    function new(self, arg)
      print("class1.new", self, arg)
      self.arg = arg		-- nothing fancy here.  just create one field.
    end

    function test(self)		-- a simple method
      print("test: class1   arg=", self.arg)
    end
}

class2 = class {		-- another class
    name = "class2"
    base = class1		-- inherit methods from class1

    -- new from class1		-- no 'new' method.  taken from class1

    function test(self)		-- overloaded method
      print("test: class2 calling class1")
      self:upper('test')	-- call method of base class
      self.arg = "world"	-- change obj
      self:upper('test')	-- call it again
    end
}

class3 = class {		-- and another one
    name = "class3"
    base = class2		-- derivative of class2

    function alloc(arg)		-- but with it's own allocator
      return arg		-- object provided by creation call
    end

    function new(self, arg)	-- has it's own 'new'
      print("class3.new", self, arg)
      self:upper('new', "foo")	-- call upper 'new' (from class1!)
      self.x = 1		-- init some more fields
      self.y = 2
      self.z = class2("foo")	-- .z is a complex object
    end
}

obj1 = class1(314)		-- create some instances
obj1b = class1(42)
obj2 = class2("hello")
obj3 = class3 {}		-- special alloc!  so {} is what obj3 becomes

obj1:show "o1"			-- now let's see what they hold
obj1b:show "o1b"
obj2:show "o2"
obj3:show "o3"

obj2:test()

print(methods(obj1)==methods(obj1b))	-- 1    same class
print(methods(obj1)==methods(obj2))	-- nil  different class