[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: patching userdata metatable.... ouch!
- From: Edgar Toernig <froese@...>
- Date: Wed, 17 Dec 2003 06:00:20 +0100
Ando,
You wrote:
>
> Goal: I now want to have it inherent from another object: x, where is
> is a table or a userdata
>
> x = { Bar = function() print("bar") end }
>
> So that after calling SetInhereitance(obj, x) I can then calll: obj:Bar()...
>
> So I want to patch in a new metatable that will, for any __index call (to
> start with) it will first call the original metatable and if something is
> found, return that. Otherwise it'll index x to see if it has anything,
> returning the result.
>
> But now matter what I try I cant get this to work. I think I have a solution
> were obj a table but not for user data. For illustration purposes, this is
> the direction I've been going:
>
> SetInheritance = function(obj, parent)
> local nmt
>
> obj.omt = getmetatable(sf)
> nmt = obj.omt
> nmt.__index = function(object, key)
> local result = rawget(object, "omt")[key]
> if result then return result end
> return parent[key]
> end
> application:SetObjectMetatable(sf, nmt)
> end
This should do it (untested):
function SetInheritance(obj, parent)
setmetatable(getmetatable(obj) or obj, { __index = parent })
end
But you have a conceptual problem! You change not only the
behaviour of 'obj' but that of all objects that use the same
metatable! Beside, the use of that function is _very_ limited.
A real class-like system needs more work[1].
Ciao, ET.
PS: Could you fix your mailer to send plain-text non-flowed
messages? Thanks.
[1] You could start with the example I sent you. Add a
'baseclass' field in each class table and let 'classmeta'
handle the inheritance instead of raising an error.