Page 17 of 25

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Wed May 11, 2011 12:53 am
by TechnoCat
I'm getting some sort of __call metamethod error using a tween callback and middleclass.

Code: Select all

Error: ./lib/middleclass/middleclass.lua:70: class Passenger doesn't implement metamethod '__call'

stack traceback:
	[C]: in function 'assert'
	./lib/middleclass/middleclass.lua:70: in function 'callback'
	./lib/tween/tween.lua:109: in function 'finishTween'
	./lib/tween/tween.lua:369: in function 'update'
	[string "main.lua"]:17: in function 'update'
	[string "boot.lua"]:320: in function <[string "boot.lua"]:308>
	[C]: in function 'xpcall'
[Finished]
The program is a visual IO scheduler. Press space-bar to start and numbers or 'r' to request blocks to be read. It crashes when it attempts to call table.remove from tween.

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Wed May 11, 2011 7:37 am
by kikito
Hi Technocat,

that is weird. I'll try to give it a look this evening.

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Fri May 13, 2011 10:48 pm
by kikito
Hi technocat,

I've found the problem. It was this tween in Elevator.lua:

Code: Select all

		tween(
				Passenger.TWEEN_TIME,
				passenger,
				{x=self.x, y=passenger.y, alpha=0},
				'inOutCubic',
				table.remove(self.passengers, #self.passengers))
The issue was on the last line; the callback must be a function (in your case, it was the result of executing table.remove, which as a person instance. Tween was trying to apply the __call metamethod to that person instance.

You can either wrap that last line within an anonymous function, like this:

Code: Select all

		tween(
				Passenger.TWEEN_TIME,
				passenger,
				{x=self.x, y=passenger.y, alpha=0},
				'inOutCubic',
				function() table.remove(self.passengers, #self.passengers) end)
Or put the function followed by its parameters:

Code: Select all

		tween(
				Passenger.TWEEN_TIME,
				passenger,
				{x=self.x, y=passenger.y, alpha=0},
				'inOutCubic',
				table.remove, self.passengers, #self.passengers)
Beware, though: on the first case #self.passengers will be evaluated when the tween finishes, and on the second it will be evaluated when the tween starts.ç

I've used the first option and it seems to work just fine. Attaching the result.

EDIT: oh and by the way, sorry for the time it took me to answer to this.

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Sat May 14, 2011 12:02 am
by TechnoCat
Yes, this pleases me very much. Thank you Kikito.

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Sun May 22, 2011 5:55 pm
by Kadoba
It's a small issue but in the comments in Apply.lua I think there's a typo on line 15. It says to call the method "includes" instead of "include". I'm just learning middleclass so this threw me for a little bit.

Code: Select all

MyClass:includes(Apply)
Edit: and another on line 49:

Code: Select all

- subclasses should also have the _istances list

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Sun May 22, 2011 6:29 pm
by kikito
Hi Kadoba,

I'm sorry the comment threw you off.

I've changed the comment so it doesn't happen to anyone else.

Thanks for reporting this!

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Fri Jun 17, 2011 6:05 pm
by LuaWeaver
I'm trying to work with middleclass, and it's just not working. Does it have to be in it's folder? I tried in and out of the folder and it did not work. I used your code here in and out of love.load().

Code: Select all

require 'middleclass.lua'
Person = class('Person') --this is the same as class('Person', Object) or Object:subclass('Person')
function Person:initialize(name)
  self.name = name
end
function Person:speak()
  print('Hi, I am ' .. self.name ..'.')
end

AgedPerson = class('AgedPerson', Person) -- or Person:subclass('AgedPerson')
AgedPerson.ADULT_AGE = 18 --this is a class variable
function AgedPerson:initialize(name, age)
  Person.initialize(self, name) -- this calls the parent's constructor (Person.initialize) on self
  self.age = age
end
function AgedPerson:speak()
  Person.speak(self) -- prints "Hi, I am xx."
  if(self.age < AgedPerson.ADULT_AGE) then --accessing a class variable from an instance method
    print('I am underaged.')
  else
    print('I am an adult.')
  end
end

local p1 = AgedPerson:new('Billy the Kid', 13) -- this is equivalent to AgedPerson('Billy the Kid', 13) - the :new part is implicit
local p2 = AgedPerson:new('Luke Skywalker', 21)
p1:speak()
p2:speak()
This is in love.

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Fri Jun 17, 2011 6:53 pm
by Robin
How is it not working? Do you get an error? If so, what does it say? etc.

(Also, to use the file called "middleclass.lua" once usually calls require 'middleclass'.)

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Sat Jun 18, 2011 8:09 am
by BlackBulletIV
You can't require files with the '.lua' extensions; it expands all dots to slashes. If you have middleclass in its folder then just go require 'middleclass.init', and in LOVE, require 'middleclass' should work too. If you have it in your main folder as a single file, just use require 'middleclass'.

EDIT: Just noticed Robin already mentioned this to a certain degree.

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Sat Jun 18, 2011 9:00 am
by Kadoba
I use the .lua extensions on all my require paths and I don't have any trouble. I believe it only expands the dots if it can't find the literal file first. (Although this may be different outside windows)