Custom typing within classes and other objects

I was curious about whether or not custom typing is possible using classes.

I’m writing a ton of classes, replacing a lot of my old code, getting ready for my skeleton game-mode release but there’s one thing I haven’t figured out how to do in just Lua ( without over-writing functions, as I did that to fix a few things )…

Example: A new PlayingCard. Notice I set __type, I have it above in the code where I define card, and as a class. I noticed if I don’t do a table.Copy of the self, the value continues to over-write itself. This example works perfectly. But, when I use print( type( card ) ) it prints as table.
[lua]//
// Create a new instance of this class.
//
function card:New( _value, object )
local __class = object or { };

local _newSelf = table.Copy( self );
setmetatable( __class, { 
	__index = _newSelf;
	__tostring = _newSelf.ToString;
	__type = "PlayingCard";
} );
_newSelf:SetValue( _value )

-- setmetatable( __class, { __index = self, __tostring = self.ToString } );
-- self:SetValue( _value )

return __class;

end[/lua]

Likewise, if I print( type( Color( 255, 255, 255, 255 ) ) in prints as table instead of Color…

So, to see if something was a color I had to do:
[lua]function IsColor( _val ) return ( type( _val ) == “table” && table.Count( _val ) == 4 && _val.r && _val.g && _val.b && _val.a ) && true || false; end[/lua]

So, my question is, is there a way to add types to current and new data-structures and classes?

This is how I currently solved it:

[lua]//
// Extended Color - Josh ‘Acecool’ Moser
//
if ( !COLOR ) then COLOR = Color; end
function Color( _r, _g, _b, _a )
local _color = COLOR( _r, _g, _b, _a );
_color.__type = “Color”;
return _color;
end[/lua]

[lua]function IsColor( _val ) return ( type( _val ) == “Color” || ( type( _val ) == “table” && table.Count( _val ) == 4 && _val.r && _val.g && _val.b && _val.a ) ) && true || false; end[/lua]

[lua]//
// Extended type - Josh ‘Acecool’ Moser
//
if ( !TYPE ) then TYPE = type; end
function type( _value )
if ( TYPE( _value ) == “table” ) then
if ( _value.__type ) then
return _value.__type;
end
end

return TYPE( _value );

end[/lua]

Now, when I print( type( card ) ) or color, or the deck of cards it outputs properly: Color, PlayingCard, DeckOfPlayingCards.

This has more uses than this, and I’m just curious if there’s a way without having to over-write built in functions. Otherwise I’ll submit a pull request with some of these upgrades.

I was trying to figure this out before too. What I learned is that you cannot change the type of any lua defined tables. You can only change the type of userdata.

What you can do, though, is add a :type() method to your classes that returns the __type variable.

Well, I rewrote the type( ) function as shown above which “solves” it. I made that as a work-around but I was hoping there was a built in “non C required” solution to add new types.

Basically “classes” or other things are considered tables, so I just made it so that all of my custom tables have a .__type which works fine. Then I modified the Color function too so it would return Color via type( ).

Anyone is free to use the type( ) override and the Color( ) override above which adds the ability.

I wonder if Garry would let me add these in a pull request, there are a ton of benefits to custom types…

I really want a __type metamethod, as it would solve this very easily.
The only problem is that lua metatables are not static, they can be changed very easy. So this would open up some vulnerabilities.

This is because you are calling SetValue on self instead of __class which is overriding the value of the metatable instead of setting it in the __class table.