Page 1 of 1

Using metatables with middleclass

Posted: Tue Jan 29, 2013 8:43 pm
by silver_hawk
I'm using middleclass for my classes in my game, and i set a lot of variables in

Code: Select all

function player:initialize()
   variables ...
   ...
   ...
end
Some of the variables are single variables but others are tables.

I was wondering if someone could point me out how to do proper getters/setters so that fx. if I want to get the variable hp, which is a table with more values,
I would get the first value in the table ie: hp[0] from player.
example

Code: Select all

hp = {[1] = 2, [2] = 4, [3] = 6}
a simple function on the player would be

Code: Select all

player:get(variable)
if type(self[variable]) == "table" then
   return self[variable][1]
else
   return self[variable]
end
but is it possible via. metatables to make this function execute using just player.hp instead of player:get("hp") ?

I've played around with the tables, but couldn't get it to work :)

Re: Using metatables with middleclass

Posted: Tue Jan 29, 2013 9:00 pm
by MarekkPie
Seems like you are coming from a Java mindset, which is fine. But if you have no need to hide the variable other than it being "good Java practice" then don't hide it.

It looks like you are going through an unnecessary loop just to make Lua mold to what you might be more familiar with.

Re: Using metatables with middleclass

Posted: Tue Jan 29, 2013 10:31 pm
by ejmr
I second MarekkPie's advice. That doesn't look like a situation where you get any benefit from getters or setters. But having said that, you can use the metatable function '__index' to execute a function, or whatever else, when accessing an element in a table.

Re: Using metatables with middleclass

Posted: Tue Jan 29, 2013 10:37 pm
by kikito
middleclass needs to use the metatables for class stuff. Simply modifying a class' metatable will not work as expected. You could try to extend the existing change the metamethods, but the setup would be complex. Also, you would be paying a performance tax every time you called a method in any instance.
I was wondering if someone could point me out how to do proper getters/setters so that fx. if I want to get the variable hp, which is a table with more values,
I would get the first value in the table ie: hp[0] from player.
example

Code: Select all

hp = {[1] = 2, [2] = 4, [3] = 6}
Forgive me for saying this, but that's a bad design. Instead, I recommend you have the information of each instance inside the instance, and then have one table holding references to the instances themselves:

Code: Select all

function Player:initialize()
  self.hp = 10
end
...
entities = {}
entities[1] = Player:new()
You will achieve the same thing, and will have the data better organized (the internal parts of each instance will be contained inside it, instead of being "spread around" into several tables).

By the way, I strongly recommend naming your classes in UpperCase and your variables and methods in lowerCase. See the naming conventions.

Re: Using metatables with middleclass

Posted: Wed Jan 30, 2013 7:38 am
by silver_hawk
Okay thank you all :) I just thought that it would be nicer to have to do the player.hp instead of player.hp[1] because I always needs the first element for things outside the player class environment, the other indexes are for internal operations :)

And ty for the naming conventions :) better bring my code to proper conventions right away :)