Metatable issue

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
jonathancyu
Prole
Posts: 3
Joined: Fri Dec 02, 2016 11:28 pm

Metatable issue

Post 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.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Metatable issue

Post 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.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
Beelz
Party member
Posts: 234
Joined: Thu Sep 24, 2015 1:05 pm
Location: New York, USA
Contact:

Re: Metatable issue

Post 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.

Code: Select all

if self:hasBeer() then self:drink()
else self:getBeer() end
GitHub -- Website
nyenye
Citizen
Posts: 62
Joined: Fri Dec 02, 2016 1:44 pm

Re: Metatable issue

Post 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!
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Metatable issue

Post 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).

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
Firehawk
Prole
Posts: 2
Joined: Sat Dec 03, 2016 2:00 pm

Re: Metatable issue

Post 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)
jonathancyu
Prole
Posts: 3
Joined: Fri Dec 02, 2016 11:28 pm

Re: Metatable issue

Post 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?
nyenye
Citizen
Posts: 62
Joined: Fri Dec 02, 2016 1:44 pm

Re: Metatable issue

Post 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
User avatar
Sir_Silver
Party member
Posts: 286
Joined: Mon Aug 22, 2016 2:25 pm
Contact:

Re: Metatable issue

Post 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.
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 6 guests