0 Replies - 1377 Views - Last Post: 06 July 2011 - 04:53 PM

#1 ishkabible  Icon User is offline

  • spelling expret
  • member icon





Reputation: 1744
  • View blog
  • Posts: 5,896
  • Joined: 03-August 09

[LUA]mini OO framework for Lua

Posted 06 July 2011 - 04:53 PM

Description: within a class declaration any key set to a non-nil variable can be inherited. __init is a metamethod that if is availed is called when an object is created, a constructor if you will. using the "extends" method you can create inheritance, multiple inheritance is not supported. the parents methods can be called but using self.super then manually passing the self reference. using the DSL shown in the example you can easily create classes to handle you OO needs.
local mt_class = {}

function mt_class:extends(parrent)
	self.super = parrent
	setmetatable(mt_class, {__index = parrent})
	parrent.__members__ = parrent.__members__ or {}
	return self
end

local function define(class, members)
	class.__members__ = class.__members__ or {}
	for k, v in pairs(members) do
		class.__members__[k] = v
	end
	function class:new(...)
		local newvalue = {}
		for k, v in pairs(class.__members__) do
			newvalue[k] = v
		end
		setmetatable(newvalue, {__index = class})
		if newvalue.__init then
			newvalue:__init(...)
		end
		return newvalue
	end
end

function class(name)
    local newclass = {}
	_G[name] = newclass
	return setmetatable(newclass, {__index = mt_class, __call = define})
end

--[[
	------------EXAMPLE------------
]]

--creates a class with 2 data members
class "Shape" {
	width = 0;
	height = 0;
}
--creates a constructor
function Shape:__init(a, b)
	self.width = a
	self.height = b
end
--creates a function that dose nothing useful,
function Shape:talk()
	print("shapes can talk? how big am i? "..self.width..","..self.height)
end

--creates a class called rectanlge that inherts from Shape
class "Rectangle" : extends(Shape) {}

--constructor has already been inhierted, no need to make it
--overloads Shape:talk
function Rectangle:talk()
	print("im a rectangle!!")
end
--new function to show how a sub-class can call it's parrents methods even if they have been overloaded
--if you need to call the parrent of a parrents method you can do self.super.super.method(self) and so on untill you have gone back sufficently far
function Rectangle:supertalk()
	self.super.talk(self)
end
--create an area function that tells us the area of a rectangle
function Rectangle:area()
	return self.width * self.height
end

--creates another class that inherits from shape, this time representing a triangle
class "Triangle" : extends(Shape) {}

function Triangle:area()
	return self.width * self.height / 2 
end

local rect = Rectangle:new(10, 10)
local tri = Triangle:new(10, 10)

print(rect:area())
print(tri:area())
print(rect:talk())
print(rect:supertalk())


Is This A Good Question/Topic? 0
  • +

Replies To: [LUA]mini OO framework for Lua

#2 ishkabible  Icon User is offline

  • spelling expret
  • member icon





Reputation: 1744
  • View blog
  • Posts: 5,896
  • Joined: 03-August 09

Re: [LUA]mini OO framework for Lua

Posted 06 July 2011 - 04:53 PM

Description: within a class declaration any key set to a non-nil variable can be inherited. __init is a metamethod that if is availed is called when an object is created, a constructor if you will. using the "extends" method you can create inheritance, multiple inheritance is not supported. the parents methods can be called but using self.super then manually passing the self reference. edit: fixed some issuesusing the DSL shown in the example you can easily create classes to handle you OO needs.
local mt_class = {}

function copy(tin)
    local tout = {}
    for k, v in pairs(tin) do
		tout[k] = v
	end
	return tout 
end

local function define(class, members)
	class.members = copy(class.super and class.super.members or {})
	for k, v in pairs(members) do
		class.members[k] = v
	end
	function class.new(...)
		local t = setmetatable(copy(class.members), {__index = class})
		local blah = t.__init and t:__init(...)
		return t
	end
end

function mt_class:extends(parent)
	self.super = parent
	parent.members = parent.members or {}
	return setmetatable(self, {__index = parent, __call = define})
end

function class(name)
	_G[name] = {}
	return setmetatable(_G[name], {__index = mt_class, __call = define})
end

--[[
	------------EXAMPLE------------
]]

--creates a class with 2 data members
class "Shape" {
	width = 0;
	height = 0;
}
--creates a constructor
function Shape:__init(a, b)
	self.width = a
	self.height = b
end
--creates a function that dose nothing useful,
function Shape:talk()
	print("shapes can talk? how big am i? "..self.width..","..self.height)
end

--creates a class called rectanlge that inherts from Shape
class "Rectangle" : extends(Shape) {}

--constructor has already been inhierted, no need to make it
--overloads Shape:talk
function Rectangle:talk()
	print("im a rectangle!!")
end
--new function to show how a sub-class can call it's parrents methods even if they have been overloaded
--if you need to call the parrent of a parrents method you can do self.super.super.method(self) and so on untill you have gone back sufficently far
function Rectangle:supertalk()
	self.super.talk(self)
end
--create an area function that tells us the area of a rectangle
function Rectangle:area()
	return self.width * self.height
end

--creates another class that inherits from shape, this time representing a triangle
class "Triangle" : extends(Shape) {}

function Triangle:area()
	return self.width * self.height / 2 
end

local rect = Rectangle:new(10, 10)
local tri = Triangle:new(10, 10)

print(rect:area())
print(tri:area())
print(rect:talk())
print(rect:supertalk())

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1