As you may know, I'm in the process of changing the way super works on middleclass.
Right now it basically modifies the scope of each method, by placing a "pantom" scope, using fenv and newenv. This is how I do it:
Code: Select all
local fenv = getfenv(method)
local newenv = {super = superDict} -- when 'super' is referenced inside method, in reality it will reference superDict (defined elsewhere)
setmetatable( newenv, {__index = fenv, __newindex = fenv} ) -- any other reference inside the method is redirected to the previous environment
setfenv( method, newenv )
1. Current solution
Code: Select all
MySuperClass = class(...)
MySubClass = class('MySubClass', MySuperClass)
function MySubClass:initialize(name)
super.initialize(self) -- super is found on newEnv.
self.name = name -- but the 'self' and 'name' references also are looked on newEnv first, and on fenv when that fails
end
function MySubClass:foo()
print(self.name) -- this function doesn't use super at all, but it gets penalyzed anyway.
end
2. hacky solution with debug.getinfo
Code: Select all
function MySubClass:initialize(name)
super.initialize(self) -- this first line is a bit slower than before...
self.name = name -- the rest is unaffected, but I had to use debug.getinfo to make it work, and that is hacky
end
3. Move it to middleclass.extras
Code: Select all
MySubClass:includes(Superable) -- without this line, the super reference doesn't work
function MySubClass:initialize(name)
super.initialize(self)
self.name = name -- but the rest is unaffected
end
4. snake-oriented super
Code: Select all
function MySubClass:initialize(name)
MySuperClass.initialize(self) -- no penalty, very similar syntax
self.name = name
end
So, what do you guys think?
I'm attaching a poll, but will use it as a reference - I'm more interested in your comments. But if you don't have time to comment, please leave the inexpressive numeric feedback.