[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Updating C structeres from Lua?
- From: RLake@...
- Date: Sat, 18 Jan 2003 15:57:46 -0500
> Problem with this approach is that the user won't be able to do stuff
> like "table.foreach(textbuffer,print)" to print all lines.
> Is there anyway around this?
Yep, write your own table.foreach :) Here's an easy one which shows
a general solution. Unfortunately, it doesn't work with syntactic
iteration (for k,v in table do ... end). I think there is an
undocumented solution to that, too.
do
local old_foreach = table.foreach
function table.foreach(obj, fn)
local meta = getmetatable(obj)
if meta and meta.__foreach then
return meta.__foreach(obj, fn)
else
return old_foreach(obj, fn)
end
end
end
> Another problem is that there is also a settings table and the user
> could change this as he pleases.
> Rather than having to go through the entire table when the script exits
> (to see what is changed) then I would prefer to supply some sort of
> callback function -- unfortunately it seems that 'newindex' (from the
> metatable) is only called when new indexes are created, and not when
> old ones are updated.
> Any way around that?
Sure, use an empty proxy table. Then you can see all accesses. For an
application like this, though, it might not make any difference; if the
user is going to edit the config table and then you're going to reread
it, you might as well scan through the whole thing afterwards, unless
there are a bunch of things that you put in there first.
Anyway, here is the basic solution. It doesn't trap get's, so it's not
that inefficient.
do
local config_table = {} -- could fill in initial values here
trigger_table = setmetamethod({},
{
__index = config_table,
__newindex = function(t, k, v)
config_changed(k, v)
config_table[k] = v
end
})
end
If you only want to trigger on certain keys, you could put other keys
into the external table directly.
In the following version, if config_changed returns nil or false,
it means "I'm not interested in this key":
do
local config_table = {} -- could fill in initial values here
trigger_table = setmetamethod({},
{
__index = config_table,
__newindex = function(t, k, v)
if config_changed(k, v)
then config_table[k] = v
else rawset(t, k, v)
end
end
})
end
Other variations are possible (like config_changed might provide a
"corrected" value.) Hope that helps.
R.