lua-users home
lua-l archive

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


On Sun, Dec 2, 2012 at 10:09 AM, steve donovan
<steve.j.donovan@gmail.com> wrote:
> On Sat, Dec 1, 2012 at 8:32 PM, Sven Olsen <sven2718@gmail.com> wrote:
>> Sadly, in the cases where I actually need an insertion-safe iteration, my
>> tables have nontrivial __newindex metamethods.
>
> Here's a fairly conventional solution, but packaged conveniently:
>
> local null = {}
>
> local modproxy_mt = {
>     __newindex = function (self,k,v)
>         if v == nil then v = null end
>         self.entries[k] = v
>     end;
>
>     commit = function(self)
>         local t = self.T
>         for k,v in pairs(self.entries) do
>             if v == null then v = nil end
>             t[k] = v
>         end
>     end
> }
> modproxy_mt.__index = modproxy_mt
>
> function modproxy (T)
>     return setmetatable({ T = T, entries = {} }, modproxy_mt)
> end
>
> Ok, the essential trick is to use a unique key 'null' as a placeholder
> for nil. With this in place, modproxy can be used like this:
>
> local T = {one=1,two=2,three=4}
>
> local pt = modproxy(T)
>
> for k,v in pairs(T) do
>     if v == 2 then
>         pt[k] = nil
>     end
>     if v == 1 then
>         pt[k..'-x'] = 1
>     end
> end
>
> pt:commit()
>
> for k,v in pairs(T) do print(k,v) end
>
> BTW, I don't care for 'modproxy', but naming things is hard ;)
>
> steve d.
>

This is more or less the same idea I had; I had only withheld comment
because a "commit"-style implementation fails if the iterator actually
needs to be able to see the modified structure.

/s/ Adam