Is type not extended...
BlitzMax Forums/BlitzMax Programming/Is type not extended...
| ||
Hi, Is there a direct way to checking if a type instance is an unextended type, instead of testing against every extended type? Type Bob; End Type Type Jim Extends Bob; End Type Type Joe Extends Bob; End Type Type Jan Extends Bob; End Type Type Jon Extends Bob; End Type Local a:bob = New bob Print "unextended bob? "+IsThisJustABob(a) ' Test against other classes, potentially ' hundreds of types would need testing, and ' some of them may be "unknown" to this part of the code Function IsThisJustABob(i:Bob) If i=Null Return False If Jim(i) Return False If Joe(i) Return False If Jan(i) Return False If Jon(i) Return False Return True EndFunction ' Hypothetical singular test Function IsThisJustABob2(i:Bob) If Unextended(Bob(i)) Return True EndFunctionI would like to avoid having to test against lots of other, potentially unknown, types, and instead simply test once. I realise I could tag a type with a custom id, but for reasons of portability etc. I would like to avoid this. |
| ||
Sadly: No there is no way to check for unextended as there is defacto nothing unextended. Everything extends from Object. It would not be really efficient to try doing so anyway. But with the stuff Mark mentioned in his worklog (reflection) you should be able to do such a check much faster as you can ask the class what it is and what is was extended from. Right now, this has to be done manually |
| ||
use a method or field with extended value true or falseType Bob Method extended(); EndMethod End Type Type Jim Extends Bob Method extended(); Return True;EndMethod End Type Type Joe Extends Bob Method extended(); Return True;EndMethod End Type Type Jan Extends Bob Method extended(); Return True;EndMethod End Type Type Jon Extends Bob Method extended(); Return True;EndMethod End Type Local a:bob = New bob Print "unextended bob? "+IsThisJustABob(a) ' Test against other classes, potentially ' hundreds of types would need testing, and ' some of them may be "unknown" to this part of the code Function IsThisJustABob(i:Bob) If i=Null Return False Return Not i.extended() EndFunction |
| ||
extended:int() you mean and return false; on bobs method, right? |
| ||
CLASS_FOO=1 CLASS_MOO=2 Type foo field class:Int Method New() class=CLASS_FOO EndMethod EndType Type moo extends foo field class:Int Method New() class=CLASS_MOO EndMethod EndType For foo=eachin something:TList Select foo.class Case CLASS_FOO Case CLASS_MOO EndSelect |
| ||
Yes, thanks :) This is how I do it right now, but I would rather do it without setting a class or extended value/method. Maybe I'm just lazy... |
| ||
So this is the obvious solution:class Bob: pass class Jim(Bob): pass def IsThisJustABob(o): return o.__class__.__name__ == "Bob" a = Bob() b = Jim() print IsThisJustABob(a) print IsThisJustABob(b) oops ... this is Python. PS: sorry, simply couldn't resist. Sorry for any inconvenience. |
| ||
Override ToString() Then you have a full string to give you all the info you want. You could for example make each type have a line, then call its supper and add another line etc. So if the first word is "BaseClass" then you know its not extended |
| ||
I'm not proud of this, and am not certain if it works on all platforms or will with future updates but interesting non-the-less...'Returns a pointer to a class for a given object 'obj' Function GetClassForObject:Byte Ptr(obj:Object) Local objPtr:Int Ptr = Int Ptr((Byte Ptr(obj)) - 8) Return Byte Ptr(objPtr[0]) End Function 'Returns a pointer to the super-class of a class pointed to by a given pointer 'class' Function GetSuperClass:Byte Ptr(class:Byte Ptr) Return Byte Ptr((Int Ptr(class))[0]) End Function 'Returns the name of a class pointed to by a given pointer 'class' Function GetClassName:String(class:Byte Ptr) If Not class Then Return Null Local debug_scope:Int Ptr = Int Ptr((Int Ptr(class))[2]) Local szClass:Byte Ptr = Byte Ptr(debug_scope[1]) Return String.FromCString(szClass) End Function 'Returns the name of the class for a given object 'obj' Function GetClassNameForObject:String(obj:Object) Return GetClassName(GetClassForObject(obj)) End Function 'Returns TRUE for an object 'obj' that has a super class named 'className', otherwise returns FALSE Function IsInstanceOf:Int(obj:Object, className:String) className = className.ToLower() Local class:Byte Ptr = GetClassForObject(obj) While GetClassName(class).ToLower() <> className class = GetSuperClass(class) If Not class Return False Wend Return True End Function Implementing your function is as simple as... Function IsThisJustABob:Int(i:Bob) Return GetClassNameForObject(i) = "Bob" End Function |
| ||
Neat. You'd probably get fired for using such a trick at work, but as the guards show you the way out you'd be walking with proud ;) |
| ||
Ah I'm liking it, Dafs. |
| ||
Now, that's more like it! Very cool Dafs! *It would be a neat addition to the language* |