[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: patching userdata metatable.... ouch!
- From: Ando Sonenblick <ando@...>
- Date: Wed, 17 Dec 2003 03:35:07 -0800
Edgar,
Thanks for your input:
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].
But I was intentionally trying just to modify obj's inheritance and not
the behavior of all objects that use the same metatable that obj
originally uses.
Conceptually I have a userdata object whose behavior is
implemented/defined by its metatable:
obj
omt
I'm basically looking to tack on another one:
obj
omt (if obj usage is handled here, do so and be done)
nmt (else, use this metatable...)
I want this to be on an object by object basis. So if I have two
objects both defined by the same metatable:
foo
omt
bar
omt
and I modify foo with another mt
foo
omt
nmt
bar is unaffected and remains
bar
omt
There's definitely a way to accomplish this - in lua you can do almost
anything. It's finding an efficient and preferably self-contained
method of doing so...
ando
On Dec 16, 2003, at 9:00 PM, Edgar Toernig wrote:
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
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.
-----------------------
Ando Sonenblick
SpriTec Software
www.spritec.com