[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: string.gsub accepting a callable userdata
- From: Coda Highland <chighland@...>
- Date: Fri, 14 Dec 2012 11:46:49 -0800
On Fri, Dec 14, 2012 at 7:35 AM, Jerome Vuarand
<jerome.vuarand@gmail.com> wrote:
> 2012/12/13 David Favro <lua@meta-dynamic.com>:
>>> local gsub,type = string.gsub,type
>>> local ref = setmetatable({}, {__weak='v'})
>>> local function unref(...) return ref[1](...) end
>>>
>>> function string.gsub(s,pat,repl)
>>> if type(repl) == 'userdata' then
>>> ref[1] = repl
>>> repl = unref
>>> end
>>> return gsub(s,pat,repl)
>>> end
>>
>>
>> Wouldn't this be non-reentrant should the called userdata itself call gsub()
>> [or cause it to be called via loaded script]? ref[1] would now be the inner
>> gsub()'s repl, and when the outer gsub() finds another match it will call
>> unref() again which will dereference to the wrong repl.
>
> Yes, you are totally right, since there is only one ref and one unref,
> if two gsub calls end up on the call stack, one will certainly have a
> wrong reference. I guess the only (simple) solution to the problem
> then is to create a closure for each gsub call.
>
Or use a stack instead of a single element. That'd work too.
/s/ Adam