lua-users home
lua-l archive

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


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.
> >
> >
>
>
>