lua-users home
lua-l archive

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



Peter Shook wrote:
For static members you can use the setfenv trick.

My previous example was too complicated. I think it's better to define the class methods within a package. Plus you can use locals for static members.

Here are some references on packages:

http://lua-users.org/lists/lua-l/2003-03/msg00101.html
http://lua-users.org/wiki/PackageSystem
http://www.lua.org/notes/ltn007.html
http://www.lua.org/notes/ltn011.html

And here is hopefully a better example:


function class(name, parent)
  local methods = {
    name   = name,
    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

  setmetatable(methods, {__call=methods.new, __index=parent})

  local function index(tab, name)
    local value = methods[name]
    if value == nil then value = _G[name] end  -- try globals
    return value
  end

  _G[name] = methods
  setfenv(2, setmetatable({}, {__index=index, __newindex=methods}))
end

------------------------------------------------------------------------------

class('List', table)

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

sm = 'something'

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

------------------------------------------------------------------------------

class('SpecialList', List)

function fun(self, a, b)
  print('SpecialList:fun', getfenv())
  return parent.fun(self, a, b)
end

------------------------------------------------------------------------------

setfenv(1, _G)  -- back to regular globals

print('_G', _G)
print('List', List)
print('SpecialList', SpecialList)
print(getfenv(List.fun), getfenv(SpecialList.fun), '\n')

a = List{'one', 2, 'three'}
print('fun =', a:fun(1,2))
a:foreach(print)

b = SpecialList{5,6,7,8}
print('fun =', b:fun(1,2))
b:foreach(print)

------------------------------------------------------------------------------

$ lua -i test.lua
_G      table: 0xa040900
List    table: 0xa047a10
SpecialList     table: 0xa048088
table: 0xa047df8        table: 0xa047cd8

List:fun        table: 0xa047df8
sm =    something
fun =   3
1       one
2       2
3       three
a       1
b       2
SpecialList:fun table: 0xa047cd8
List:fun        table: 0xa047df8
sm =    something
fun =   4
1       5
2       6
3       7
4       8
a       1
b       2
> b:append(a)
> b:foreachi(print)
1       5
2       6
3       7
4       8
5       one
6       2
7       three
> = b:getn()
7
>