Page 1 of 1

Metatable issue

Posted: Tue Dec 13, 2016 3:42 am
by jonathancyu
I'm trying to apply these two metamethods

Code: Select all

__add = function(this, obj)
	return vector.new(self.x + obj.x, self.y + obj.y)
end,

__sub = function(this, obj)			
	return vector.new(self.x - obj.x, self.y - obj.y)
end,
to the table

Code: Select all

local self = {
	["x"] = x and x or 0,
	["y"] = y and y or 0
}
but am getting the error
attempt to perform arithmetic on field 'x' (a table value)
Does anyone know why this is happening? As far as I know, x is a number value.

Re: Metatable issue

Posted: Tue Dec 13, 2016 5:02 am
by s-ol
jonathancyu wrote:I'm trying to apply these two metamethods

Code: Select all

__add = function(this, obj)
	return vector.new(self.x + obj.x, self.y + obj.y)
end,

__sub = function(this, obj)			
	return vector.new(self.x - obj.x, self.y - obj.y)
end,
to the table

Code: Select all

local self = {
	["x"] = x and x or 0,
	["y"] = y and y or 0
}
but am getting the error
attempt to perform arithmetic on field 'x' (a table value)
Does anyone know why this is happening? As far as I know, x is a number value.
context is everything here, 'as far as you know' x is a number value, but lua is telling you it's not. the code you show is fine, but it's being used wrong somehow somewhere.

Re: Metatable issue

Posted: Tue Dec 13, 2016 5:03 am
by Beelz
It's hard to tell without seeing the implementation in your code... Try adding this and see what you get.

Code: Select all

print( string.format('x=%s, y=%s', tostring(x), tostring(y)) )
Otherwise your best bet is to upload a .love and let us know where the code in question is.

Re: Metatable issue

Posted: Tue Dec 13, 2016 7:50 am
by nyenye
First of all, the first argument ought to be self, either way you shouldn't get access to self.

Also you shouldn't create a table named self as a local var. self should be reserved to class methods only.

Know that you can declare a method to be called with ':' instead of '.' and it will take self as first argument, without need to specify it. This should get you somewhere:

http://lua-users.org/wiki/SimpleLuaClasses
http://lua-users.org/wiki/ObjectOrientationTutorial

Good luck!

Re: Metatable issue

Posted: Tue Dec 13, 2016 4:22 pm
by s-ol
nyenye wrote:First of all, the first argument ought to be self, either way you shouldn't get access to self.

Also you shouldn't create a table named self as a local var. self should be reserved to class methods only.

Know that you can declare a method to be called with ':' instead of '.' and it will take self as first argument, without need to specify it. This should get you somewhere:

http://lua-users.org/wiki/SimpleLuaClasses
http://lua-users.org/wiki/ObjectOrientationTutorial

Good luck!
he can't use ':' because he is directly adding them to a table at instantiation time. (sure he could rewrite more but it's unnecessary changes). You are right though that 'this' should be 'self' (or 'self' should be 'this', but 'self' is the Lua convention and should be used).

Re: Metatable issue

Posted: Tue Dec 13, 2016 9:53 pm
by Firehawk
I had to make an assumption in here, but here's what you asked for as far as I could figure out

Code: Select all

--Vector implemented globally. With the implementation suggested, this must be a global or else the metamethods don't know what a
--vector is. Take a look into scope if you want to know more on this.

vector = {
	mt = {
		__add = function(a, b)
		   return vector.new(a.x + b.x, a.y + b.y)
		end,

		__sub = function(a, b)         
		   return vector.new(a.x - b.x, a.y - b.y)
		end
	},
	
	new = function(x, y)
		return setmetatable({x=x, y=y}, vector.mt)
	end
}

local p1 = vector.new(1, 1)
local p2 = vector.new(2, 2)

local p3 = p1 + p2

print(p3.x, p3.y)
Instead of an implementation such as

Code: Select all

local self = {   <--Not a good variable name.
  ["x"] = x and x or 0,
  ["y"] = y and y or 0
}

I'm unable to figure out what type of object this is. Is this how you're choosing to instance your vector?
If this is some type of game entity, its metatable wouldn't really be a vector. Make sure to name your variables more descriptively.

Code: Select all

local entity = {
  position = vector.new(0, 0),
}

entity.position.x = 10
entity.position.y = 20
Remember: In a method call, lua defines "self" as the table invoking the call. Read more on metatables for a better understanding of that.

Code: Select all

local tbl_a = {}

function tbl_a:method()
  self.a = 1
end

--In this case, self refers to tbl_a
tbl_a:method() 

--In this case, self also refers to tbl_a
tbl_a.method(tbl_a)

local tbl_b = {}

--In this case, self refers to tbl_b.
tbl_a.method(tbl_b)

Re: Metatable issue

Posted: Wed Dec 14, 2016 3:34 am
by jonathancyu
The intention is for this to be a very simple vector class so I can manipulate 2d positions easily.
Here's the full code http://pastebin.com/Hmz9cfGz
I used the self variable because I'm using it as an object. Is that not what I'm supposed to use it for?

Re: Metatable issue

Posted: Wed Dec 14, 2016 6:34 am
by nyenye
I recomend that you look into HUMP library. It has two libs for vectors, Vector (using tables) and Vector-light (not using tables).

As they always say, dont reinvent the wheel

Re: Metatable issue

Posted: Thu Dec 15, 2016 9:29 pm
by Sir_Silver

Code: Select all

local tab = {}
tab.phrase = "Hello, I am a phrase!"

function tab:print_phrase()
    print(self.phrase)
end

tab:print_phrase()
Self is a local variable automatically available for you to use when you are defining a method of a table, if you have another table named self - which in your example you do - you won't be able to access it inside of another table's method without creating a new variable with a different name to point to your "self" table.