|
On Dec 13, 2012 1:03 PM, "Jerome Vuarand" <jerome.vuarand@gmail.com> wrote:
>
> 2012/12/13 steve donovan <steve.j.donovan@gmail.com>:
> > That does work - gsub respects __index, which is nice (I had to check this)
> >
> > Best global solution in such a situation is the following monkey patch:
> >
> > local gsub,type = string.gsub,type
> >
> > function string.gsub(s,pat,repl)
> > if type(repl) == 'userdata' then
> > local obj = repl
> > repl = function(...) return obj(...) end
> > end
> > return gsub(s,pat,repl)
> > end
>
> To avoid the creation of a closure on each call, you can cache one:
>
> 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
>
You want __mode='v', not __weak. And I'm not sure why you're using a table to store that one item. It's not necessary to use a table to create local upvalues:
local gsub,type = string.gsub,type
local ref
local function unref(...) return ref(...) end
function string.gsub(s,pat,repl)
if type(repl) == 'userdata' then
ref = repl
repl = unref
end
return gsub(s,pat,repl)
end
Although this function just looks like an elaborate noop... is it needed at all?