This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
viluon's profile picture

OOP Table definition

Started by viluon, 18 May 2014 - 03:21 PM
viluon #1
Posted 18 May 2014 - 05:21 PM
Hello, PROs!

I have an Object Oriented API which defines some GUI elements.
I ran into a problem with inheritance of objects that have tables inside themselves.
My code is based on http://www.lua.org/pil/16.2.html with a custom new() function:
New=function(this,...)
  object = {}
  setmetatable(object,this)
  this.__index=this
  return object
end,
(it works, hope it's "grammatically" okay)
However, I noticed that when creating a new instance of my class that looks like
myObject={
  position={
	x=1,y=1,
  },
}
(plus the new() function) the final object's (local test=myObject:new()) position.x is not accessible.
It looks like it cannot be inherited from the parent class until I add sth like
test.position={}
test.position.x=6
--#OR
test.position={x=6,...}
Is there any solution for this problem? Defining position again and again ruins up the thought of OOP…

Thanks for any reply!

Sincerely, viluon
Edited on 18 May 2014 - 03:23 PM
MKlegoman357 #2
Posted 19 May 2014 - 05:54 PM
Hmm, there was something a little similar to me.

I don't see the exact problem, but I see some things which should be changed.

With your current setup the table position would be global to any other instance of that object (remember that variables only hold table pointers, not tables themselves). What I would suggest would be:

A. create the object inside the new function.

B. create all variables, which are going to be changed, inside the new function.

A:

local function new (x, y)
  local object = {
    position = {
      x = x;
      y = y;
    }

    foo = function (this)
      print("Position: ", this.x, "x", this.y)
    end;
  }

  return object
end

local object = new(1, 2)
local object2 = new(3, 4)

print(object.position.x) -->> 1
print(object2.position.x) -->> 3

object:foo() -->> Position: 1x2
object2:foo() -->> Position: 3x4

B:

local class
class = {
  foo = function (this)
    print("Position: ", this.x, "x", this.y)
  end;

  __index = class;

  new = function (this, x, y)
    local object = {
      position = {
        x = x;
        y = y;
      }
    }

    setmetatable(object, this)

    return object
  end
}

local object = class:new(1, 2)
local object2 = class:new(3, 4)

print(object.position.x) -->> 1
print(object2.position.x) -->> 3

object:foo() -->> Position: 1x2
object2:foo() -->> Position: 3x4
Edited on 19 May 2014 - 03:55 PM
viluon #3
Posted 19 May 2014 - 06:27 PM
Thank you MKlegoman.
I actually solved it about 15 minutes ago :D/> but never mind, your approach seems interesting. What I did is pretty simple (w8, did you understand my code clearly? my new() function is inside the object, I said plus the new function, sorry if it wasn't obvious), I changed the metatable of position to this.position (inside the constructor) and added __index, so my new() looks like
new=function(this,...)
  object = {}
  setmetatable(object,this)
  object.position={}
  setmetatable(object.position,this.position)
  this.__index=this
  this.position.__index=this.position
  return object
end,
It works, I wanted to edit the post but first wanted to continue the dev bcs I don't have much spare time today. An(d)yway, thanks for your reply! I appreciate your help :)/>


Sincerely, viluon (Andy)
MKlegoman357 #4
Posted 19 May 2014 - 06:44 PM
I understood that the 'new' function was inside the object. Also, setting __index property inside the class every time you call 'new' is not a very good solution. Just put it inside the class variable once like I did in B example.