[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: adventures with iterators
- From: Coda Highland <chighland@...>
- Date: Sun, 2 Dec 2012 10:43:26 -0800
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