Page 2 of 3
Re: Create a class without external libraries
Posted: Sat Feb 13, 2016 8:51 am
by Roland_Yonaba
Implementing OOP with closures is a nice, simple and elegant method though. I am definitely not advocating against, but for the sake of discussion, I would just like to point out it seems this approach involves
more memory consumption.
Steve Litt also discussed the topic
here.
I would love to hear your own thoughts about that.
Re: Create a class without external libraries
Posted: Sat Feb 13, 2016 7:16 pm
by Kibita
Take a look at this on reddit:
https://www.reddit.com/r/love2d/comment ... sses_work/
The user
imaginaryrobots shows how he makes his classes. He's doing right? Because it seems good to me (the code itself)
Re: Create a class without external libraries
Posted: Sat Feb 13, 2016 8:11 pm
by rmcode
Roland_Yonaba wrote:I would love to hear your own thoughts about that.
I am using the Closure Based Approach in all of my projects and so far I didn't have any problems with it. Obviously I don't have a comparison though, but with the metatable approach each object uses two tables which also take up memory whereas an object with the closure based approach only uses one (even if you use extensive inheritance).
This is how easily you can implement inheritance:
Code: Select all
local ParentClass = {};
function ParentClass.new()
local self = {};
return self;
end
return ParentClass;
Code: Select all
local ChildClass = {};
function ChildClass.new()
local self = ParentClass.new(); -- Use the table from the parent class.
return self;
end
return ChildClass;
Re: Create a class without external libraries
Posted: Sat Feb 13, 2016 8:14 pm
by Inny
Lua is itself inconsistent in how classes should be built. Strings have a hidden metatable that points via __index at the string table. However files have a hidden metatable that points at itself, which doesn't exist under _G anywhere.
Generally speaking, the method in Pil where you have Class.__index = Class is the closest to official and probably the most compatible between all of the libraries that would use classes. In the reddit thread you mention, imaginaryrobot's is this method. I tend to not like to assign the self.__index = self bit, but rather would write Queue.__index = Queue where the class is first created (the line after local Queue = {}), mostly because it's a good idea to design classes to not change anymore after you've returned their class object from the module. I'll show you my method and explain everything:
Code: Select all
local Foo = {} -- create class object
Foo.__index = Foo -- only change an object while we're still building it.
function Foo:new( ... )
local inst = setmetatable({}, self) -- self in this context *could* be Foo, but could be a subclass
inst:init(...) -- call an init function in case there's a Subclass doing an override
return inst
end
function Foo:init(your, code, here)
-- self in this context is the instance
end
return Foo
As mentioned, this enables subclasses
Code: Select all
local Foo = require('foo')
local Bar = {}
for k, v in pairs(Foo) do Bar[k] = v end -- subclass via copying
-- Alternatively, you can subclass by Making Bar's metatable be Foo
Bar.__index = Bar -- And correctly point Bar's instances as the subclass.
function Bar:init(other, code, here)
Foo.init(self, parameters)
-- other initialization
end
return Bar
Re: Create a class without external libraries
Posted: Sat Feb 13, 2016 11:12 pm
by bobbyjones
rmcode wrote:Roland_Yonaba wrote:I would love to hear your own thoughts about that.
I am using the Closure Based Approach in all of my projects and so far I didn't have any problems with it. Obviously I don't have a comparison though, but with the metatable approach each object uses two tables which also take up memory whereas an object with the closure based approach only uses one (even if you use extensive inheritance).
How does each object use 2 tables? Metatables are one table shared between all objects.
Re: Create a class without external libraries
Posted: Sat Feb 13, 2016 11:16 pm
by rmcode
Ah yes ... my bad. I just meant that the difference in memory consumption is probably negligible.
Re: Create a class without external libraries
Posted: Sat Feb 13, 2016 11:34 pm
by bobbyjones
rmcode wrote:Ah yes ... my bad. I just meant that the difference in memory consumption is probably negligible.
If you have a couple hundred objects I believe that the metatables method would probably be much more efficient on terms of memory. Idk about in performance tho.
Re: Create a class without external libraries
Posted: Sun Feb 14, 2016 12:16 am
by Kibita
Inny wrote:Lua is itself inconsistent in how classes should be built. Strings have a hidden metatable that points via __index at the string table. However files have a hidden metatable that points at itself, which doesn't exist under _G anywhere.
Generally speaking, the method in Pil where you have Class.__index = Class is the closest to official and probably the most compatible between all of the libraries that would use classes. In the reddit thread you mention, imaginaryrobot's is this method. I tend to not like to assign the self.__index = self bit, but rather would write Queue.__index = Queue where the class is first created (the line after local Queue = {}), mostly because it's a good idea to design classes to not change anymore after you've returned their class object from the module. I'll show you my method and explain everything:
[/code]
It's necessary to use the
init function?
Re: Create a class without external libraries
Posted: Sun Feb 14, 2016 12:42 am
by s-ol
rmcode wrote:Ah yes ... my bad. I just meant that the difference in memory consumption is probably negligible.
It is not if you have many objects because your approach creates a new set of member (and private!) functions for every object. So if you have 5 methods and 4 private helper functions and you create 10 instances you have 90 different functions an 9 tables in memory. With metatables you have 9 functions and 10 tables.
That is unless luajit can optimize this to keep just one instance of each function with a different closure, but I'm not sure whether that's possible and it would still make 9 functions, 90 closures and 9 tables.
Also it you want to do operator overloading, read only attributes, fallbacks or something of the like you need metatables anyway.
All that said, I do like the idea of the closure-way, but it nearly makes the table obsolete; you could have all the attributes live in the closure too and just pass around the methods.
Oh - and why do you need the colon syntax with the closure approach? It works 100% the same if you just leave it out, the functions inherit the 'self' upvalue from the constructor.
Re: Create a class without external libraries
Posted: Sun Feb 14, 2016 1:00 am
by rmcode
S0lll0s wrote:Oh - and why do you need the colon syntax with the closure approach? It works 100% the same if you just leave it out, the functions inherit the 'self' upvalue from the constructor.
It's just my own flavor:
Easier to read IMO.