lua-users home
lua-l archive

Re: On lua5 and embedding

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


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

AltStyle によって変換されたページ (->オリジナル) /