Reflection Bug + Soln
Archives Forums/BlitzMax Bug Reports/Reflection Bug + Soln
| ||
Hey, just came across this error: TTypeID.ForObject() will always return Null when executed in the constructor method of a global object declared in the scope of a type. Consider this code: Type mytype Global objectvar:mytype = New mytype Method New() Local obj:Object = New mytype2 Print TTypeId.ForObject( obj ).name() 'BUG HERE! End Method End Type Type mytype2 End Type This should reasoably print "mytype2". But an EAV is what you get. Took me a while to track this down tho, so please fix this soon! A temporary solution is to move the global into file scope. This would not make TTypeID.ForObject( objectvar ) (from the example) work, but thats fine, as you would barely reflect an objects type within its own constructor. |
| ||
Type mytype2 End Type Type mytype Global objectvar:mytype = New mytype Method New() Local obj:Object = New mytype2 Print TTypeId.ForObject( obj ).name() 'BUG HERE! End Method End Type This one works. It seems TTypeId.ForObject needs the type declared earlier in the code in order to recognize it. |
| ||
Thats strange. I mean, this seems to contradict all previous experiences where declaration order of functions and types just didnt seem to matter. Thanks for your reply! |
| ||
Has anything been done on this yet, anyone? At least an explanation of the inconsistent behaviour would be nice. Last edited 2010 |
| ||
The problem is the order of declaration (clearly). Types are registered in the same order that they are declared, but globals inside of types are registered before the type gets registered (which should probably be changed, barring any other issues from an order change). For example, with the original, the linear declaration order is: Type mytype Global objectvar:mytype Type mytype2 Thus the order of calls will be: _bb_mytype_objectvar = bbObjectNew(mytype) bbObjectRegisterType(bb_mytype) bbObjectRegisterType(bb_mytype2) The mytype.New() method cannot access type information on mytype2 because it hasn't yet been registered. With the working example by Difference, the order of mytype2 is before the declaration of objectvar and mytype: Type mytype2 Type mytype Global objectvar:mytype Then the call order is: bbObjectRegisterType(bb_mytype2) _bb_mytype_objectvar = bbObjectNew(mytype) bbObjectRegisterType(bb_mytype) The safest solution (for example, if the mytype.New() method needs to know type information about mytype) would be to move the global below (or above) both declarations, but that would remove it from mytype. Moving the objectvar declaration out of and above or below the type declarations would work because all type members are instantiated and registered before global globals. Last edited 2010 |
| ||
Thank you! - that really clears things up for me. I thought it was a compiler bug, but that makes sense. Last edited 2010 |