[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Checking if a table has changed
- From: "Leandro Candido" <enclle@...>
- Date: Fri, 12 Dec 2003 04:55:21 -0200
Hello All,
IF and IF you want, Florian, you can use a function (initializer) to
create each table, too, it's easy to use:
-- begin code
function t( thetable )
local meta = {}; -- or create a global one.
function meta.__newindex( self, name, value )
-- do what you want (track the value, etc...)
-- ... --
print(self, name, value); -- comment for normal use.
rawget(self,"_______X")[name] = value; -- to allow meta call of
__newindex for X, if it has a metatab, see example in TWICE part below
end
function meta.__index( self, name )
-- do what you want here...
-- ... --
print(self,name);
return rawget(self,"_______X")[name]; -- to allow meta call of __index
for X.
end
local tab = { _______X = thetable }
setmetatable( tab, meta);
return tab;
end
mytable = t{ xyz = "123", lua_version = _VERSION }
another = t(mytable);
print(mytable.xyz);
print(mytable.lua_version);
print(mytable.nilfield);
print("\nNow the metamethods will be called twice (THIS IS TO BE CALLED
TWICE):");
print(another.xyz);
print(another.lua_version);
print(another.nilfield);
print("\nNow, this will break our schema, of course:");
mytab = t{}
setmetatable(mytab,{});
print(mytab.nilfield);
-- end code
You can "seach and replace" all "{" with "t{" in your .lua files, and you
will have what you want, but this can't be made automagically, as Virgil (or
others) stated.
The God's Peace,
Leandro.
----- Original Message -----
From: "Virgil Smith" <virgil@nomadics.com>
To: "'Lua list'" <lua@bazar2.conectiva.com.br>
Sent: Thursday, December 11, 2003 2:59 PM
Subject: RE: Checking if a table has changed
> I suggest you check the wiki and the list archives for Lazy Copy or Deep
> Copy (and/or RLake as I think he submitted the one I'm thinking of at the
> moment).
>
> You can copy any table placed into your hierarchy (using a proxy table at
> each level). This may seem inefficient, but I can't think of any other
> language in which you wouldn't have the same basic copy problem (though I
> don't doubt others have). Basically, this relates to a question of
> ownership of an "object" and/or to attributes of the "object's" type (in
> this case a "modified" flag). You could restrict tables added to your
> hierarchy to be of a given "type" that supports a "modified" flag (and a
> parent pointer for passing modification notices up the hierarchy if you so
> choose). The "type" of a table in Lua is related to its metatable.
>
> An aspect of the copy approach is that you cannot be sure that "other"
> references to the original table did not exist at the time that the table
in
> question was inserted into your hierarchy. However, one approach to this
> would be to "hijack" the original table as the proxy table. In other
words
> rather than copying the contents of a table that is being "inserted" into
> your hierarchy, you could <move> the contents into another table. This
> would result in any "stray" references to the inserted table going through
> one of your proxy tables and thus you can maintain your "modified" flag.
> One problem with this approach is that you must not only "hijack" the base
> table, but also its metatable if it already has one. However, a Lua table
> with a metatable is essentially a user defined type, object, or "class
> instance", and "seeing through" an unknown type to determine if it has
been
> modified etc. is not a simple problem in any language. Naturally,
> userdata's are just as much of an "unknown type" as tables with
metatables,
> and threads and functions bring up their own issues (though I'm not at all
> sure about the "issues" with functions in this context).
>
> Anyhoo, just my suggestions, perhaps you'll even find them useful. :-)
> Also, if my use of the term "hierarchy" seems strange, try rereading the
> message using "tree" in its place.
>
>
>
> -----Original Message-----
> From: lua-bounces@bazar2.conectiva.com.br
> [mailto:lua-bounces@bazar2.conectiva.com.br]On Behalf Of Florian Berger
> Sent: Thursday, December 11, 2003 8:25 AM
> To: Lua list
> Subject: Re: Checking if a table has changed
>
>
>
> Thanks for the tip! I found code from lua-l archive (see below, I
> modified it a little bit). The problem is that as you can see that it
> does not work for nested tables. I could traverse recursively the
> subtables through and call proxy for each table but I cannot do this
> because of performance reasons. This cannot be automated somehow?
>
> Floru
>
>
> Source: http://lua-users.org/lists/lua-l/2003-07/msg00173.html
>
> do
> local signature = {}
>
> -- set a proxy on table
> function proxy(table)
> local meta =
> {
> __index = table,
>
> __newindex = function(_, index, value)
> print('Modified!')
> table[index] = value
> end,
>
> __signature = signature,
> }
>
> return setmetatable({}, meta)
> end
>
> local n = next
>
> -- next replacement to support pairs and "old style" for loops
> function next(table, index)
> local m = getmetatable(table)
> return n(m and m.__signature == signature and m.__index or table,
> index)
> end
> end
>
> local x = proxy( {{a = 1}, a = 1, b = 2} )
>
> for k, v in pairs(x) do
> print(k, v)
> end
>
> x[1].a = 5
> x.a = 2
>
>
> Result:
> 1 table: 00379EB8
> a 1
> b 2
> Modified!
>
>
>
>
> Jamie Webb wrote:
>
> > On Thursday 11 December 2003 08:22, Florian Berger wrote:
> >
> >>Hi.
> >>
> >>Is there a simple and efficient way to check if a table has changed? By
> >>using metatables I'm able to catch some modifications but not all of
them.
> >
> >
> > You could use a proxy table with a __newindex which makes modifications
to
> the
> > actual table and sets a 'modified' flag. Since the proxy table stays
> empty,
> > __newindex is always called.
> >
> > -- Jamie Webb
> >
> > There are only 10 types of people in this world:
> > those who understand binary, and those who don't.
> >
> >
>
>
>