middleclass & extras: middleclass 3.0 is out!

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
TechnoCat
Inner party member
Posts: 1611
Joined: Thu Jul 30, 2009 12:31 am
Location: Milwaukee, WI
Contact:

Re: middleclass & extras: middleclass 2.0 is out!

Post by TechnoCat »

It prints

Code: Select all

true
It works as a global though.

EDIT: I haven't tested it because I'm in class, but I bet it will work if I require inside of the entered callback instead of on a file scope level.
EDIT2: Nope. Also didn't make any sense when I put it in code. :neko:
Attachments
shmup.love
(110.39 KiB) Downloaded 171 times
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: middleclass & extras: middleclass 2.0 is out!

Post by kikito »

Hi technocat,

I've found the problem.

You had this code inside: lua/state/Menu.lua:

Code: Select all

local Shmup = require 'lua.shmup'
However, lua.shmup was not a file; it was a directory - lua/shmup/ . When LÖVE requires a folder, it automatically tries to append "init.lua" to that folder. Which is what happened here - the line above was in reality doing Shmup = require 'lua.shmup.init'

But the init.lua file was not returning the Shmup class:

Code: Select all

local _path = ({...})[1]:gsub("%.init", "")

return require( _path .. '.Shmup' )
Hence the error. I'm still a bit surprised that the require returned "true" instead of "nil" though.

If you change init.lua to return the Shmup class, it works (attaching working version) but since you are going to include more classes inside the shmup folder, I'd either return a table called shmup containing all of them (shmup.Shmup, shmup.Foo, etc) or just make them global and be done with it.

Regards!
Attachments
shmup.love
(109.96 KiB) Downloaded 159 times
Last edited by kikito on Fri Oct 14, 2011 6:29 pm, edited 1 time in total.
When I write def I mean function.
User avatar
slime
Solid Snayke
Posts: 3163
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: middleclass & extras: middleclass 2.0 is out!

Post by slime »

About require returning true rather than nil:
Once a loader is found, require calls the loader with a single argument, modname. If the loader returns any value, require assigns the returned value to package.loaded[modname]. If the loader returns no value and has not assigned any value to package.loaded[modname], then require assigns true to this entry. In any case, require returns the final value of package.loaded[modname].
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: middleclass & extras: middleclass 2.0 is out!

Post by kikito »

Interesting. The more you know...
When I write def I mean function.
Indigo gem
Prole
Posts: 3
Joined: Fri Dec 23, 2011 12:40 pm

Re: middleclass & extras: middleclass 2.0 is out!

Post by Indigo gem »

Is it invalid use to call super class initialize like this?

Test1 = class("Test1")
Test2 = class("Test2", Test1)
Test3 = class("Test3", Test2)

function Test3:initialize(params)
self.super.class.initialize(self, params) -- go in infinite recursion call
end

this works for Test1 -> Test2 but for Test1 -> Test2 -> Test3 not works because initialize go in infinite recursion call
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: middleclass & extras: middleclass 2.0 is out!

Post by kikito »

Hi Indigo Gem,

I have just tried your code. I just made one change: Instead of

Code: Select all

self.super.class.initialize(self, params)
The class and super had to be switched:

Code: Select all

self.class.super.initialize(self, params)
Here's the complete code:

Code: Select all

require 'middleclass'

Test1 = class("Test1")
Test2 = class("Test2", Test1)
Test3 = class("Test3", Test2)

function Test3:initialize(params)
  self.class.super.initialize(self, params)
end

local obj = Test3:new()
This worked just fine - it run without giving me any errors or entering any infinite loop.

Is the code that you used here complete, or is there any missing stuff? Notably - are there definitions of Test1.initialize and/or Test2.initialize?

I'm asking because you are using this construction:

Code: Select all

self.class.super.initialize
If you used self.class.super inside the Test2 initializer, you will get an infinite loop if self is an instance of Test3. For instances of Test3, "self.class" is always Test3, and "self.class.super" is always Test2 ... even on methods inherited from Test2! In consequence, "self.class.super.initialize" always refers to "Test2.initialize". If you call it from itself, you get an infinite loop.

The only solution is not using "self.class.super", but using the class instead:

Code: Select all

Test2.initialize(self, params)
If the code you have pasted there is complete (there are no missing constructors, etc) then your version of middleclass is probably not updated. Try again with the latest version.
When I write def I mean function.
Indigo gem
Prole
Posts: 3
Joined: Fri Dec 23, 2011 12:40 pm

Re: middleclass & extras: middleclass 2.0 is out!

Post by Indigo gem »

here code I used, I admit I make a mistake when typing (dont write constructers etc.), but this is full code below dont work

Code: Select all

require "middleclass"

local Test1 = class("Test1")
local Test2 = class("Test2", Test1)
local Test3 = class("Test3", Test2)

function Test1:initialize(params)
end
function Test2:initialize(params)
self.class.super.initialize(self, params) 
end
function Test3:initialize(params)
self.class.super.initialize(self, params) -- go in infinite recursion call
end

local t = Test3{}
I am tested this in Corona SDK btw, (lua 5.1), here is log

Code: Select all

Copyright (C) 2009-2011  A n s c a ,  I n c .
	Version: 2.0.0
	Build: 2011.704
The file sandbox for this project is located at the following folder:
	(/Users/sergey/Library/Application Support/Corona Simulator/engine-2419A65E500758E2AE1AF33CF8CAA007)
Runtime error
	/Users/sergey/projects/engine/main.lua:50: stack overflow
stack traceback:
	[C]: ?
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	...
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:53: in function 'initialize'
	/Users/sergey/projects/engine/middleclass.lua:90: in function </Users/sergey/projects/engine/middleclass.lua:88>
	(tail call): ?
	/Users/sergey/projects/engine/main.lua:56: in main chunk
Runtime error: /Users/sergey/projects/engine/main.lua:50: stack overflow
stack traceback:
	[C]: ?
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	...
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:50: in function 'initialize'
	/Users/sergey/projects/engine/main.lua:53: in function 'initialize'
	/Users/sergey/projects/engine/middleclass.lua:90: in function </Users/sergey/projects/engine/middleclass.lua:88>
	(tail call): ?
	/Users/sergey/projects/engine/main.lua:56: in main chunk
so I'll just use explicit call of super class
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: middleclass & extras: middleclass 2.0 is out!

Post by kikito »

Hi,

I'm pretty sure that the loop doesn't happen in Test3, but in Test2. But yes, use explicit classes instead of self.class and you should be fine. Also, show us what you end up doing, even if it's in Corona :) !
When I write def I mean function.
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: middleclass & extras: middleclass 2.0 is out!

Post by Roland_Yonaba »

Hi,

I was wondering about the use of Invokermixin, by itself.
Basically, it calls a method or a property of an instance.
But why would one do:

Code: Select all

obj:invoke('method',...)
instead of

Code: Select all

obj:method(...)
I don't see the point. Maybe you can provide me some examples ?
And by the way, I guess the error messange on checking MiddleClass should be corrected ('Please require it before using Invoker, not Beholder').
User avatar
TechnoCat
Inner party member
Posts: 1611
Joined: Thu Jul 30, 2009 12:31 am
Location: Milwaukee, WI
Contact:

Re: middleclass & extras: middleclass 2.0 is out!

Post by TechnoCat »

Roland_Yonaba wrote:Hi,

I was wondering about the use of Invokermixin, by itself.
Basically, it calls a method or a property of an instance.
But why would one do:

Code: Select all

obj:invoke('method',...)
instead of

Code: Select all

obj:method(...)
I don't see the point. Maybe you can provide me some examples ?
And by the way, I guess the error messange on checking MiddleClass should be corrected ('Please require it before using Invoker, not Beholder').
I'm guessing because with invoke you can pass it a variable string that gets invoked.
Post Reply

Who is online

Users browsing this forum: No registered users and 8 guests