Table Funcs

lua-users home
wiki

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 4:15 pm GMT (diff)