lua-users home
lua-l archive

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


On Thu, 30 Aug 2007 11:25:13 +0200
Michal Kolodziejczyk <miko@wp.pl> wrote:

> Hello,
> I woul like to write some classes (to get some OO and inheritance),
> which could also be modules (to get autoload and "dotted" names
> notation). What is the way to accomplish it?
> 
> [..]
> 
> Is it possible to implement something like this in pure lua? Where
> should I start? Should I redefine module/require, or is there another
> way? I could do it if module(name, func1, ...) could call func1 with a
> parameter (e.g. parent class) or with "self", but it cannot.

I've come up with the following pattern, which has solidified over time
and I use quite frequently now. Add deeply nested class paths on your
own discretion:

-- atom.lua:
local getfenv, setmetatable = getfenv, setmetatable
module "atom"
local Atom = getfenv()
__index = Atom
function Atom.new(class, self)
  return setmetatable(self or { }, class)
end
function Atom.newclass(baseclass, class)
  class = class or { }
  class.__index = class
  return setmetatable(class, baseclass)
end

-- polygon.lua:
local Atom = require "atom"
local getfenv, print = getfenv, print
module "polygon"
local Polygon = Atom:newclass(getfenv())
function Polygon.new(class, self)
  self = Atom.new(class, self or { })
  self.edges = self.edges or 3
  return self
end
function Polygon:print()
  print("edges:", self.edges)
end

-- application.lua:
local Polygon = require "polygon"
local RedSquare = Polygon:newclass()
function RedSquare.new(class, self)
  self = self or { }
  self.edges = 4
  self.color = "red"
  return Polygon.new(class, self)
end
function RedSquare:print()
  Polygon.print(self)
  print("Color:", self.color)
end
local t1 = RedSquare:new()
t1:print()

The trick is to place the class in the module table using getfenv().
(Also note that unlike the PIL, I differentiate between new() and
newclass() for the sake of clarity - and I believe that this is also
slightly more efficient.) Comments?

- Timm

-- 
Timm S. Mueller <tmueller@neoscientists.org>