Jump to content
  • Advertisement
Sign in to follow this  

lua Class implementation not working, using __index

This topic is 3050 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Thought i would liven up the scripting thread a bit. I have an issue with my class implentation
Class = function( prototype )
	local derived = {}
	local derivedMT = {
		--When indexing into a derived class, check the base class as well
		__index = prototype,
		--When invoking a class, return an instance
		__call = function( proto, ... )
			local instance = {}
			local instanceMT = {
				--When indexing into an instance, check the class hierarchy as well.
				__index = derived,
				--Calling instances is a no-no!
				__call = function() 
					print( "WARNING! Attempt to invoke an instance of a class!" )
					print( debug.traceback() )
					return instance
			setmetatable( instance, instanceMT )
			if ( instance.__constructor ) then
				instance:__constructor( ... )
			return instance
	setmetatable( derived, derivedMT )
	return derived	
for some reason when i try thing = class() function thing:Hello() print("hello") end SpecialThing = class(thing) SpecialThing:Hello(); it doesnt work! i should be able to call the base class function right? it sets the index property of the metatable? am i missing something? I can post my exact usage if this doesnt point out the problem. thanks...

Share this post

Link to post
Share on other sites
I haven't debug your class impl. but I've been using this one for awhile and it does everything I need.

function inheritsFrom( baseClass )

local new_class = {}
local class_mt = { __index = new_class }

function new_class:create()
local newinst = {}
setmetatable( newinst, class_mt )
return newinst

if nil ~= baseClass then
setmetatable( new_class, { __index = baseClass } )

-- Implementation of additional OO properties starts here --

-- Return the class object of the instance
function new_class:class()
return new_class;

-- Return the super class object of the instance, optional base class of the given class (must be part of hiearchy)
function new_class:baseClass(class)
return new_class:_B(class);

-- Return the super class object of the instance, optional base class of the given class (must be part of hiearchy)
function new_class:_B(class)
if (class==nil) or (new_class==class) then
return baseClass;
elseif(baseClass~=nil) then
return baseClass:_B(class);
return nil;

-- Return true if the caller is an instance of theClass
function new_class:_ISA( theClass )
local b_isa = false

local cur_class = new_class

while ( nil ~= cur_class ) and ( false == b_isa ) do
if cur_class == theClass then
b_isa = true
cur_class = cur_class:baseClass()

return b_isa

return new_class

This is a slightly modified version of the one found on the Lua wiki. The difference is you pass the current class instance to get the super class (as the original code called it, i call it the base class), this is to support chained inheritance. The original code didn't work when the inheritance depth was greater than 1.

You would use it like so:

LevelBase = inheritsFrom( nil ); -- Create a table to hold the class methods
function LevelBase:new() -- The constructor
local object = {mBaseStuff={1,2,3}};
setmetatable(object, {__index = LevelBase}); --setup metatable
return object

function LevelBase:callFunc(a,b)
print("base class function called "..a..","..b);

LevelDerived= inheritsFrom( LevelBase );
function LevelDerived:new() -- The constructor
local object = LevelBase:new();
setmetatable(object, {__index = LevelDerived}); --setup metatable
return object

function LevelDerived:callFunc(a,b)
print("derived class function called "..a..","..b);

function LevelDerived:callFuncBase(a,b)

To call a base class function you will have to use this somewhat arcane convention.


--or if you only have a single inheritance depth :


note the usage of the . calling convention and passing in self as the first param, that's needed, you can't use the : convention.

Hope this help! Enjoy!


Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!