Yonaba / Lua-Class-System

Lua Class System (LCS) is a small library which offers a clean, minimalistic but powerful API for (Pseudo) Object Oriented programming style using Lua.
http://yonaba.github.com/Lua-Class-System
64 stars 17 forks source link

Stack Overflow? #4

Open awilliamson opened 11 years ago

awilliamson commented 11 years ago

Using the extends method, and upon calling self:super("init",params) from within my extended class' init function It appears to recursively call.

[ERROR] gamemodes/inpsb/gamemode/classes/../classes/hudpanel.lua:7: stack overflow
  1. super - gamemodes/inpsb/gamemode/classes/../classes/hudpanel.lua:7
   2. super - gamemodes/inpsb/gamemode/classes/../classes/hudpanel.lua:7
    3. super - gamemodes/inpsb/gamemode/classes/../classes/hudpanel.lua:7
     4. super - gamemodes/inpsb/gamemode/classes/../classes/hudpanel.lua:7
      5. super - gamemodes/inpsb/gamemode/classes/../classes/hudpanel.lua:7
       6. super - gamemodes/inpsb/gamemode/classes/../classes/hudpanel.lua:7
        7. super - gamemodes/inpsb/gamemode/classes/../classes/hudpanel.lua:7
         8. super - gamemodes/inpsb/gamemode/classes/../classes/hudpanel.lua:7
          9. super - gamemodes/inpsb/gamemode/classes/../classes/hudpanel.lua:7

HudPanel.lua:

local HudComponent = GM.class.getClass("HudComponent")
local C = HudComponent:extends()

function C:init(x, y, width, height, backgroundColor, autosize)
    self:super("init",x, y, width, height)
        ... etc

HudComponent.lua:

local C = GM.LCS.class()

function C:init(x, y, width, height)
    self.x = x
    self.y = y
        ... etc

I can't see anything wrong with that as a class extension, any help is much appreciated.

NB - Not sure if I've given you enough to diagnose the issue here, but I would have to put the whole system on otherwise, due to the way I integrated the class system into my creation system.

Yonaba commented 11 years ago

Hmm, strange. I can't see what's going on from the sample, you might want to show a bit more. It seems you made LCS module global, and GM.LCS being a reference to this. Class C (in HudComponent.lua) seems to be the root class here, created via GM.LCS.class(). Which is fine.Then, in HudPanel.lua, how come the new class C is get from GM.class.getClass(''HudComponent") ? I am not sure about what's behind that reference, as I was expecting it to be a direct reference to C (in HudComponent.lua) class ?

awilliamson commented 11 years ago

I'm rolling a custom class creation system. GM.class is that system and getClass just retrieves classes which I've saved to it. I use that for getting classes into individual class files, for use in extending. The self:super call was doing a recursive issue with only HudPanel ( which is the most commonly derived class ), for the other classes which are derived very little if at all, the original self:super method worked.

For the HudPanel I had to use self:getClass():init(args) for it to work non-recursively. Is there any limitation onto the number of classes which can extend one class. I have a lot of other classes which extend HudPanel.

Yonaba commented 11 years ago

Hi, sorry for the delay. Ach...I see what's going on here. Well, it seems there's a recursion issue when the inheritance tree reaches two (or more) levels of depth. This is due to the internals of the library. I'll fix that, when I have the chance.

Anyway, as a very simple workaround, instead of calling super, which can result in a stack overflow problem, you can explicitely call the superclass constructor. See the examples below:

local LCS = require 'lcs'

local A = LCS.class()
function A:init(a)
    self.a = a
end

local AA = A:extends()
function AA:init(a,b)
    A.init(self,a)
    self.b = b
end

local AAA = AA:extends()
function AAA:init(a,b,c)
    AA.init(self, a, b)
    self.c = c
end

local a = AAA(1,2,3)
for k,v in pairs(a) do
        print(k,v)
end

Output:

>lua -e "io.stdout:setvbuf 'no'" "t.lua" 
a   1
c   3
b   2
>Exit code: 0

You can altenaltively dive into 30log, which solves this problem.

awilliamson commented 11 years ago

Yeah had a feeling it was a limit with extension of classes. Currently got your lib running for my class system, got to say It's working well.

The new way which I'm making the classes I need I shouldn't require more than 3 levels, but if you're working on a fix, that's great.

Invoking the class method directly is a little bit bad, I'd prefer not to do it if possible, although I usually only use it during Init and Render and It only ever calls the super method, never another class, so it's not too bad.

Thanks for looking into it.

csun commented 11 years ago

Was just having this exact same problem. Perfect timing for the creation of this issue. Hope you get it fixed, and thanks for the useful library.

awilliamson commented 11 years ago

Hopefully this gets fixed at some point. I don't know at the current time If I'm going to require the use of 3 or so extensions, as the full system I'm working with isn't designed yet.

Can we get a time frame on a fix?