lua-users home
lua-l archive

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


Here's one I don't recall seeing mentioned in this discussion:

"Object Inversion"
------------------
This is another way to store the private attributes in function
closures. We avoid creating new closures for each object by using
attribute tables indexed by self (which remains empty unless there are
public attributes).

module "Rectangle"

-- Tables which hold attributes
local weak = { __mode = "k" }
local width = setmetatable({}, weak)
local height = setmetatable({}, weak)

-- The table of methods
local methods = {}
local meta = { __index = methods }

-- The constructor
function new(w, h)
	local self = {}
	width[self] = w
	height[self] = h
	return setmetatable(self, meta)
end

-- A method which uses the private attributes
function methods:area()
	return width[self] * height[self]
end

-- Inheritance function
function subclass()
	return { width = width, height = height, methods = methods }
end


PROS:
- Good privacy
- Uses standard method call notation
- Uses fairly nice class definition notation
- Possible to have public attributes also
- Time/space overheads roughly the same as 'classic' objects
- Can choose whether each attribute is private or protected
- Unlike straight closures, time/space performance doesn't degrade for
  large numbers of methods

CONS:
- Uses weak tables, so there is a danger of uncollectable reference
  cycles (but the Python folks don't seem too distraught about that)
- Not as fast as straight closure objects for attribute access
- Uses non-standard syntax for attribute access
- Have to explicitly permit inheritance
- Any more? I've never actually tried this method...

-- Jamie Webb