lua-users home
lua-l archive

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


Ok, I've spent some ours to get a decent object system from lua.
Here is what I've done. The nice thing is that I've removed the ':' syntatic sugar, now you must use only the '.' operator.

Please test it, abuse it and find obscure bugs or improve it.

--
()_() | Always keep the Titanic in mind when I talk        | +----
(o.o) | about security or safety, meaning that nothin      | +---+
'm m' | is fully secure.                                   |  O  |
(___) |              raffaele punto salmaso presso libero punto it
GPG fingerprint 1CF5 51D4 E528 EB87 9977  B277 BE8C BF1E 620C 40ED
--
-- Copyright (C) 2004, Salmaso Raffaele <raffaele@salmaso.org>
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
--  1. Redistributions of source code must retain the above copyright notice,
--     this list of conditions and the following disclaimer.
--  2. Redistributions in binary form must reproduce the above copyright
--     notice, this list of conditions and the following disclaimer in the
--     documentation and/or other materials provided with the distribution.
--  3. If the binary program depends on a modified version of this package,
--     you are encouraged to publicly release the modified version of this
--     package.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.

-- operator overloading
-- __add +
-- __mul *
-- __sub -
-- __div /
-- __le <=
-- __lt <
-- __eq ==
-- __tostring
-- __call ()
-- __index []
-- __newindex
-- __pow ^
-- __unm
-- __concat ..

function class(super)
	-- create a new class description
	local klass = {}
	-- set the superclass (for object inheritance)
	setmetatable(klass, {
		__index = super,
		__call = function(self, ...)
			tmp = {}
			setmetatable(tmp, klass)
			self.init(tmp, unpack(arg))
			return tmp
		end
	})
	klass.__index = function(table, key)
		local r = klass[key]
		if table ~= klass and type(r) == 'function' then
			return function(...) r(table, unpack(arg)) end
		else
			return r
		end
	end
	return klass
end

-- ######################
-- test the object system
-- ######################

Object = class()
function Object.init(self, name)
	self.name = name
end
function Object.print(self)
	print(self.name)
end
function Object.__call(self)
	print('Object.__call')
end

o = Object('ciao')
o.print()
Object.print(o)

Widget = class(Object)
function Widget.init(self, name)
	Object.init(self, name)
end

Button = class(Widget)
function Button.init(self)
	Widget.init(self, 'button')
end
function Button.clicked(self)
	print('button.clicked')
end
function Button.click()
	print('Button.click')
end

w = Widget('widget')
w.print()

b = Button()
b.clicked()
--b.click() no!
--b.click yes
Button.click()

num = class()
function num.init(self, n)
	self.n = n
end
function num.__add(self, other)
	return self.n + other
end
function num.__tostring(self)
	return "" .. self.n
end
function num.__pow(self, n)
	local t = self.n
	while n > 0 do
		t = t * self.n
		n = n - 1
	end
	return t
end
function num.__call(self)
	print(self.n)
end

a = num(1)
print(a)
a = a + 23
print(a)
a = a^3
print(a)