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)
  end

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

  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
    end
    setfenv(func, setmetatable({}, {__index=index, __newindex=env}))
  end

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

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

  return methods
end

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

List.sm = 'something'

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

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

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

a:foreach(print)


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