lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

Andre de Leiradella wrote:
Does anybody have ideas on this subject?

Hi Andre,

For static members you can use the setfenv trick. Here is an example, but beware I didn't test this as much as I usually do because I have a lunch date that I'm late for.

I recomend using parent:doSomething(a, b, c) for explicitly calling
inherited methods.

- Peter Shook

function class(parent)
  local methods = {parent = parent}
  local mt = {__index = methods}

  function methods:new(obj)
    return setmetatable(obj or {}, mt)

  function methods:copy(obj, ...)
    local newobj = obj:new(unpack(arg))
    for n,v in pairs(obj) do newobj[n] = v end
    return newobj

  local function fix_env(func)
    local env=getfenv(func)
    local function index(tab, name)
      local value = methods[name]  -- get static member
      if value == nil then value = env[name] end  -- get global
      -- rawset(tab, name, value)  -- cache value
      return value
    setfenv(func, setmetatable({}, {__index=index, __newindex=env}))

  local function newindex(tab, name, value)
    rawset(tab, name, value)
    if type(value)=='function' then fix_env(value) end

  local class_mt = {
    __call  =,
    __index = parent,
    __newindex = newindex,
  setmetatable(methods, class_mt)

  return methods

function printf(...) io.write(string.format(unpack(arg))) end

List = class(table)

function List:push(x) @insert(x) return self end
function List:pop() return @remove() end
function List:shift() return @remove(1) end
function List:append(list)
  for _,elem in ipairs(list) do @insert(elem) end
  return self
end = 'something'

function List:fun(a, b)
  @a = a
  @b = b
  print('sm =', sm)
  return @getn()

a = List{'one', 2, 'three'}

print('fun =', a:fun(1,2))


$ lua text.lua
sm =    something
fun =   3
1       one
2       2
3       three
a       1
b       2