Custom types in Lua
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Custom types in Lua
Pardon if this has already been discussed somewhere else. Searched the forum but could not seem to find anything.
Lets say I've defined a table for a certain "class" with metamethods and I want this "class" to have its own type definition so that if I used as argument for the type() function it would return something else other than "table".
Is this possible to do this just in lua or do you know of any nice workaround to achieve something similar?
As a bonus, I recently found out about the FFI library in LuaJIT which allows you to define c-data-structures and function bindings directly in lua-code. You can define new types (checked by a different function though) here but after some testing I don't think I would be able to convert all the classes I would like to due to some of their fields are tables.
http://luajit.org/ext_ffi.html
Lets say I've defined a table for a certain "class" with metamethods and I want this "class" to have its own type definition so that if I used as argument for the type() function it would return something else other than "table".
Is this possible to do this just in lua or do you know of any nice workaround to achieve something similar?
As a bonus, I recently found out about the FFI library in LuaJIT which allows you to define c-data-structures and function bindings directly in lua-code. You can define new types (checked by a different function though) here but after some testing I don't think I would be able to convert all the classes I would like to due to some of their fields are tables.
http://luajit.org/ext_ffi.html
Re: Custom types in Lua
I think someone suggested a __type metamethod once on the lists but it didn't gain any traction. For any "class" where you want to check if some object is an "instance" of it, you could just put a property in the prototype like isWhatever = true. If you're doing this kind of typechecking so much that that would be inconvenient, you're probably not using the language in an idiomatic way.
I suppose you could also write a function taking an "instance" and a "class," and walk up the prototype chain until you either hit the "class" you were looking for or the end of the chain.
I suppose you could also write a function taking an "instance" and a "class," and walk up the prototype chain until you either hit the "class" you were looking for or the end of the chain.
Re: Custom types in Lua
You could have a __type metamethod and then override the default type() function to call the metamethod if it has it, or otherwise call the old type function if it doesn't.
Last edited by szensk on Mon Jun 15, 2015 9:50 pm, edited 1 time in total.
Re: Custom types in Lua
Shadowing type sounds like asking for trouble, it's going to take anyone else looking at the code a few minutes to figure out what you've done. Might as well make a new function for it. But why use a meta-property when you can just stick a property in the prototype and check that? Nobody's likely to complain if your Dude class has a property like isDude = true; no reason to go digging around in a metatable for it.szensk wrote:You could have a __type metamethod and then override the default type() function to call the metamethod if it has it, or other was call the old type function if it doesn't.
Re: Custom types in Lua
A __type metamethod sounds like it could be pretty useful indeed. Fortunately I only need this for a rather specific case right now so checking by property will probably suffice.time thief wrote:I think someone suggested a __type metamethod once on the lists but it didn't gain any traction. For any "class" where you want to check if some object is an "instance" of it, you could just put a property in the prototype like isWhatever = true. If you're doing this kind of typechecking so much that that would be inconvenient, you're probably not using the language in an idiomatic way.
I suppose you could also write a function taking an "instance" and a "class," and walk up the prototype chain until you either hit the "class" you were looking for or the end of the chain.
Could you elaborate on your second suggestion? Would it be something like:
Code: Select all
function checkType(instanceTable , originalClassTable)
-- Compare fields, return true or false
end
That is a valid option too. I suppose "__type" could be named anything as it doesn't exist in the lua-api.szensk wrote:You could have a __type metamethod and then override the default type() function to call the metamethod if it has it, or other was call the old type function if it doesn't.
Re: Custom types in Lua
I think it might do more harm than good. It's nice knowing that type will return one of a small set of possible values. If you want to know whether something is a function or table, but instead type is returning something like "monster," it's going to be an excercise in frustration... which is another good reason not to shadow type as suggested in another reply (if shadowing built-in stuff doesn't raise enough red flags on its own).Lugen wrote:A __type metamethod sounds like it could be pretty useful indeed.
Yeah, keep it simple.Lugen wrote:Fortunately I only need this for a rather specific case right now so checking by property will probably suffice.
I could, but I'd rather not... I don't think it's a great solution; it sort of encourages long inheritance chains. But basically you would just get the metatable for instanceTable, and get its __index property, and that's your new instanceTable, and keep doing that until instanceTable is equal to either originalClassTable or nil. Of course that makes some assumptions about how you've handled classes/inheritance, but it should work for most cases.Lugen wrote:Could you elaborate on your second suggestion?
- ejmr
- Party member
- Posts: 302
- Joined: Fri Jun 01, 2012 7:45 am
- Location: South Carolina, U.S.A.
- Contact:
Re: Custom types in Lua
Personally if I know that (for example) a function parameter is going to be a class in the form of a table then I will check its type, if necessary, by looking at its metatable, e.g.:
If you use a third-party library for OOP then it may already provide something to that effect, although I got the impression from your post that you're not using anything like that.
Code: Select all
if getmetatable(object) == WhateverClass.Metatable then ... end
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: Custom types in Lua
Let me start by saying that when doing OOP, "asking something what's his type" is considered a "bad smell in the code". There are some cases where it is reasonable to do so, but in general what you do is implementing methods in that class/type.
This is how you would do a "type switch" with middleclass, using instanceOf:
And this is how you would use that function in an object:
But in object oriented programming what's recommended do is creating a method in A and B:
Then you can just do this:
The "if-else-if-else" is done "automatically" for you. There is another advantage: Imagine that you do the "function with ifs" thing more than once or twice. And then imagine that you add a new class called C. Then you will have to "hunt" all places where you made a "class switch" and manually change them. Using the second option, you just need to create C, implement the class-specific methods on it (like printClass) and the code that worked for A and B will also work for C. No "hunting" needed.
This is how you would do a "type switch" with middleclass, using instanceOf:
Code: Select all
function printClass(obj)
if obj:instanceOf(A) then
print('Class A')
else if obj:instanceOf(B) then
print('Class B')
end
end
Code: Select all
printClass(x)
But in object oriented programming what's recommended do is creating a method in A and B:
Code: Select all
function A:printClass()
print('Class A')
end
...
function B:printClass()
print('Class B')
end
Code: Select all
x:printClass()
When I write def I mean function.
Re: Custom types in Lua
tl;dr: duck typingkikito wrote:Let me start by saying that when doing OOP, "asking something what's his type" is considered a "bad smell in the code". There are some cases where it is reasonable to do so, but in general what you do is implementing methods in that class/type.
This is how you would do a "type switch" with middleclass, using instanceOf:
And this is how you would use that function in an object:Code: Select all
function printClass(obj) if obj:instanceOf(A) then print('Class A') else if obj:instanceOf(B) then print('Class B') end end
Code: Select all
printClass(x)
But in object oriented programming what's recommended do is creating a method in A and B:
Then you can just do this:Code: Select all
function A:printClass() print('Class A') end ... function B:printClass() print('Class B') end
The "if-else-if-else" is done "automatically" for you. There is another advantage: Imagine that you do the "function with ifs" thing more than once or twice. And then imagine that you add a new class called C. Then you will have to "hunt" all places where you made a "class switch" and manually change them. Using the second option, you just need to create C, implement the class-specific methods on it (like printClass) and the code that worked for A and B will also work for C. No "hunting" needed.Code: Select all
x:printClass()
Re: Custom types in Lua
Could you explain what you mean by that? To me that post seems to be about favoring subtype polymorphism over typechecking; I'm not seeing the connection to duck typing.Xgoff wrote:tl;dr: duck typing
Who is online
Users browsing this forum: Bing [Bot] and 8 guests