Reflection Question: Generalized Object Dumper

BlitzMax Forums/BlitzMax Programming/Reflection Question: Generalized Object Dumper

zoqfotpik(Posted 2014) [#1]
I'm trying to write a general object dumper function:
function dumpobject(thisobject:Object)

and will print out all information about that object including its typename-- eg if we had a type
Type TMytype
Field x, y, z
End Type

testobject:TMyType = new TMyType


and we call dumpobject, it will print out
Object Type: TMyType
Name: testobject
Field x:int 34
Field y:int 22340978
Field z: int 9001


Thoughts?


Polan(Posted 2014) [#2]
Check out reflection module. I think it has methods you will find usefull for this :).


zoqfotpik(Posted 2014) [#3]
Maybe I will look at Brucey's reflection module and see if I can understand it better from there.


BlitzSupport(Posted 2014) [#4]
This is a modified example of someone else's code (apologies to "someone else")...
Strict

Type TMyType
	Field x:Byte
	Field y:Double
	Field z:String = "Hello"
End Type

Function DumpObj (obj:Object)

	Local id:TTypeId = TTypeId.ForObject (obj)
	
	Print "Type name: " + id.Name ()
	
	For Local fld:TField = EachIn id.EnumFields ()
	
		Print "Field: " + fld.Name ()
		
		Select fld.TypeId ()
		
			Case ByteTypeId
				Print "Byte"
			Case ShortTypeId
				Print "Short"
			Case IntTypeId
				Print "Int"
			Case LongTypeId
				Print "Long"
			Case FloatTypeId
				Print "Float"
			Case DoubleTypeId
				Print "Double"
			Case StringTypeId
				Print "String"
			Default
				Print fld.TypeId ().Name ()
				
		End Select

	Next

End Function

Local test:TMyType = New TMyType

DumpObj test



zoqfotpik(Posted 2014) [#5]
Thank you. This is pretty much what I was looking for.

I can see how generalized object dumping is sort of complex, to really do it would require drilling down into user-defined subobjects (similar to deep copies.)

So basically for user defined subtypes it would need custom drilldown code. And that's probably fine.

The above code could be made into a realtime tweaker-- a development and debugging utility to modify game variables realtime without much effort. I was working on one of those a while back, maybe I will have another poke at it.

For anyone wondering why, for balancing games the above is a HUGE AMOUNT faster than having to change things in a text file or code numerous times, reloading or compiling each time. Loading from a parameter file is better obviously but you don't want to write that every time, instead make a tweaker (even on the console) that will handle that stuff. That way when you want to adjust some character's jump height you can do that. It should be super easy to do with tweakable ints, this dump code makes it easier even than that.

Usually around here, "someone else" is equal to Brucey.


Derron(Posted 2014) [#6]
There is no need to use that whole "select" portion, as the typeIDs contain their names (like you see in the default case):

	For Local fld:TField = EachIn id.EnumFields ()
		Print "Field: " + fld.Name() + "  "+fld.TypeId().Name()
	Next



@deep copies (cloning)
You need to take care of things like "references". If you want to copy an object, it is sometimes needed to "do things again". Eg when cloning an object containing a tlist/tmap: you then should traverse along the entries and add them to a new "tlist" (more exact: object of the same type of the object which extended a tlist), this new list is then to return as the copy/clone.


I extended code posted here some years ago:
https://github.com/GWRon/Dig/blob/master/base.util.helper.bmx


It uses type specific methods (CloneObject) to enable adjusted handling (eg you extend from tlist but add some more reference tables).



bye
Ron


zoqfotpik(Posted 2014) [#7]
You need to take care of things like "references". If you want to copy an object, it is sometimes needed to "do things again". Eg when cloning an object containing a tlist/tmap: you then should traverse along the entries and add them to a new "tlist" (more exact: object of the same type of the object which extended a tlist), this new list is then to return as the copy/clone.

Right, I picked up on that fairly quickly a few years back. I was just using that as a superficially similar example.

I added your THelper to my lib.