[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: On lua5 and embedding
- From: Björn De Meyer <bjorn.demeyer@...>
- Date: Wed, 29 Jan 2003 19:50:36 +0100
Luiz Henrique de Figueiredo wrote:
>
> >As for the __get and __set issue, proxy tables can
> >indeed be used, however, it would be nice if there was
> >an example in the official distribution.
>
> See readonly.lua, trace-globals.lua, and undefined.lua in test/ .
> They use limited proxies (not totally empty tables), though.
>
As those weren't to my liking, I wrote my own example
which follows below, which allows the metamethods
__get and __set to be used. The idea is that you use
the function makeproxy() directly after setting the
metatable and use that proxy as a replacement for the
real table. I haven't tested the other methods like
__add, __sub, etc but it should also work for those metamethods.
Comments and improvements are welcome. I
would especially appreciate Jimmyp_gr's comments,
as he requested such functionality.
__proxy__index = function
(t,i)
local meta = getmetatable
(t)
if
meta.__get
then return
meta.__get(meta.target,i)
else return meta.target[i];
end
end
__proxy__newindex = function
(t,i,v)
local meta = getmetatable
(t)
if
meta.__set
then
meta.__set(meta.target,i,v)
else meta.target[i] =
v
end
end
function
makeproxy(tab)
local proxy,
meta
meta =
getmetatable(tab)
proxy = { }; -- always
empty
proxymeta = {
}
if
meta
then for k, v in meta do
rawset(proxymeta,k,v)
end
end
-- copy the metatable, to get the
operators.
proxymeta.__index =
__proxy__index
proxymeta.__newindex =
__proxy__newindex
-- override these
two.
proxymeta.target =
tab;
-- so we know whom we are
proxying!
setmetatable(proxy,
proxymeta);
return proxy;
end
-- example metatable, with the much desired __get and __set
methods.
tabmeta =
{
__get = function(t,i) print "__get called!" return rawget(t, i)
end,
__set = function(t,i,v) print "__set called!" rawset(t, i,v)
end,
__call = function() print "__call called!"
end,
__unm = function() print "__unm called!"
end
}
mytab =
{
first = "first
string"
}
setmetatable(mytab,tabmeta)
mytab =
makeproxy(mytab)
-- this is how "makeproxy" should be called.
-- some tests
-- __get and __set from metatable should be
called.
print(mytab.first)
mytab.first = "First string
again!"
print(mytab.first)
print(mytab.second)
mytab.second = "Second
line"
print(mytab.second)
mytab.second = "Second line
again!"
print(mytab.second)
mytab();
fake = -mytab;
--
"No one knows true heroes, for they speak not of their greatness." --
Daniel Remar.
Björn De Meyer
bjorn.demeyer@pandora.be