lua-users home
lua-l archive

Re: New object system in 7 LoC

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


great trick
honestly, i prefer the way that javascript does.
but the lua way is not bad :-)
easy to keep c-api and lua-api in the same style.
于 2011年11月20日 20:27, Stefan Reich 写道:
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

AltStyle によって変換されたページ (->オリジナル) /