Table Funcs


The flip side of tables which look like functions is functions which look like tables.

do
 local meta = {__call = function(t, ...)
 return t.__function(t, unpack(arg))
 end
 }
 function Tablefunc(fn)
 return setmetatable({__function = fn}, meta)
 end
end

The result of Tablefunc is a table with call semantics, but the function has an implicit first argument which is its own table, in which it can store persistent state.

I know what you're thinking. So what? This is just a standard object call without the key. And what if I want private persistent state? OK, take a look at TableFuncsTwo

Meanwhile, here is a quick and silly example:

repeater = Tablefunc(
 function(self, n, str)
 -- I've got persistent state variables
 self.times_called = (self.times_called or 0) + 1
 -- I can get at the base function and even change it
 -- so it will do something different next time
 if self.times_called >= 99 then
 self.__function =
 function() return "Sorry, I'm tired of repeating myself" end
 end
 -- I can use the table for configuration, and
 -- the functable itself is self, so I can recurse
 if n == 0 then return ""
 elseif n == 1 then return str
 else return str .. (self.delim or ", ") .. self(n - 1, str)
 end
 end)

The obligatory sample run:

$ lua
Lua 5.0 (beta) Copyright (C) 1994-2002 Tecgraf, PUC-Rio
> -- I can get at the state variables from here, too
> repeater.delim = "; "
> print(repeater(7, "hello"))
hello; hello; hello; hello; hello; hello; hello
> print(repeater.times_called)
7
> _ = repeater(90, "hello")
> print(repeater.times_called)
97
> print(repeater(7, "hello"))
hello; hello; Sorry, I'm tired of repeating myself

--RiciLake

Another implementation:
function wrap(fn)
 local t = {}
 return function(...) return fn(t, ...) end, t
end
or this:

local states = setmetatable({}, {__mode = "kv"})
function addstate(fn)
 local t = {}
 local fn2 = function(...) return fn(t, ...) end
 states[fn2] = t
 return fn2
end
function getstate(fn)
 return states[fn]
end
--DavidManura

RecentChanges · preferences
edit · history
Last edited May 28, 2007 11:15 am GMT (diff)

AltStyle によって変換されたページ (->オリジナル) /