[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: New object system in 7 LoC
- From: Stefan Reich <stefan.reich.maker.of.eye@...>
- Date: Sun, 20 Nov 2011 12:27:11 +0000
Hi guys!
I just created a neat little object system for Lua (5.1) that does pretty much exactly what I want.
You use it like this:
newThing = object(function() -- could add arguments here too
var1 = 1
local var2 = 'test'
function method1()
var1 = var1+1
end
local function method2()
return string.sub(var2, 2) -- can use globals as normal
end
end)
thing = newThing()
thing.var1 = 5
thing.method1() -- yeah, just dot, no colon
The point is: You just put all fields and methods inside one big definition function. What you declare 'local' will be private; everything else will become part of the object.
The great advantage: No need to ever write 'self.'. (I'm coming from the Java world and I just hate having to insert 'self' all the time (or at all).)
Also, all non-local variables are both readable and writeable from outside.
Usually I write a module 'plain' first (everything top-level) and decide to make it an object later. With this system, I can do that without changing one bit in the code.
There is one little caveat: The definition function must not be recursive (making more objects of its own kind); that would probably break the setfenv trickery. Making more objects within methods is fine.
Here's how it is implemented. Attention, it's short - 14 lines with comments and whitespace :)
*****
-- make an object from a definition function.
-- all variables and functions declared in the definition function without 'local'
-- are automatically part of the new object.
function makeObject(definition, ...)
-- make an environment that inherits all the globals
local env = setmetatable({}, {__index = function(_, k) return _G[k] end})
setfenv(definition, env)(...)
return env
end
-- the beloved curry operator (for one fixed arg)
function curry(f, a) return function(...) return f(a, ...) end end
function object(definition) return curry(makeObject, definition) end
*****
You can also put it all in one function, but it still ends up taking 7 LoC:
***
function object(def)
return function(...)
local env = setmetatable({}, {__index = function(_, k) return _G[k] end})
setfenv(def, env)(...)
return env
end
end
***
Is this old? Is this new? Has this been done before? I love this and I think I'll be using it to death. :)
Cheers,
Stefan