Could we have a built-in Repr$() method?

BlitzMax Forums/BlitzMax Programming/Could we have a built-in Repr$() method?

Warpy(Posted 2008) [#1]
Wouldn't it be great if every object had a method Repr$() which returned a string describing the object, and which the Print command would implicitly call, so we can do stuff like:
Type dude
  field name$, lives

  Method Repr$()
    Return name+" ("+lives+" lives)"
  End Method
End Type

jim:dude=new dude
jim.name="Jim"
jim.lives=5

Print "You are playing as "+jim


Please don't tell me this already exists, I've been kludging round it for ages.


Mahan(Posted 2008) [#2]
Maybe something like this? Just pass the repr() function any object.

EDIT: Reread your post: well, it isn't implicit, but it's a description.

SuperStrict

Function repr:String(o:Object)
	Const CRLF:String = Chr(13) + Chr(10)
	Local s:String
	Local ti:TTypeId = TTypeId.ForObject(o)
	s = "Class: " + ti.Name() + CRLF
	For Local fld:TField = EachIn ti.EnumFields()
		s:+"  " + fld.Name() + "(" + fld.TypeId().Name() + "): " + fld.GetString(o) + CRLF
	Next
	Return s
End Function

Type TTest
	Field hi:String = "Hi"
	Field value:Float = 0.5
	Field hug:Int = True
	Field arr:Int[]
	Field ref:TTest
End Type

Local test:TTest = New TTest
Print repr(test)


Or you can make your own selfclass that overrides the built-in method toString() of Object:

SuperStrict


Type SelfDescribingBaseClass
	Method ToString:String()
		Const CRLF:String = Chr(13) + Chr(10)
		Local s:String
		Local ti:TTypeId = TTypeId.ForObject(Self)
		s = "Class: " + ti.Name() + CRLF
		For Local fld:TField = EachIn ti.EnumFields()
			s:+"  " + fld.Name() + "(" + fld.TypeId().Name() + "): " + fld.GetString(Self) + CRLF
		Next
		Return s
	End Method
End Type

Type TTest Extends SelfDescribingBaseClass
	Field hi:String = "Hi"
	Field value:Float = 0.5
	Field hug:Int = True
	Field arr:Int[]
	Field ref:TTest
End Type

Local test:TTest = New TTest
Print test.ToString()




tonyg(Posted 2008) [#3]
Type 'ttypeid' into MaxIde and F1F1.
It'll list the methods available with reflection which includes 'Fields' which are returned in a list.


ziggy(Posted 2008) [#4]
Ummm... isn't that what ToString() is suposed to do? If not, reflection is your friend as Mahan explains in his code sample.


plash(Posted 2008) [#5]
I was thinking the same, ziggy..


Brucey(Posted 2008) [#6]
I was thinking the same, ziggy..

Phew... for a moment there I thought I was using it wrong...


Warpy(Posted 2008) [#7]
What does ToString() do? Anyway, unless that in fact does what I want, I think you're all missing the point that I want to have a nice shorthand in string concatenation so I can do stuff like that Print statement at the end, just using the object variable and not calling a method explicitly.


Brucey(Posted 2008) [#8]
Would this be True then, if your code worked as you intend?

If String(jim) Print "I am a string"

..which would cause me all kinds of issues, given that I often use variable:Object parameters, allowing me to pass various object types (including strings) into a function.


AlexO(Posted 2008) [#9]

What does ToString() do? Anyway, unless that in fact does what I want, I think you're all missing the point that I want to have a nice shorthand in string concatenation so I can do stuff like that Print statement at the end, just using the object variable and not calling a method explicitly.



every object has a 'toString()' method. Is your main motive trying to avoid typing it or avoiding having to know which object it is to call the method explicitly?


Mahan(Posted 2008) [#10]
Well, i tried to compile it first without the .ToString() at the end but that didn't work.

On the other hand I have always been an enemy to "hidden overriding of operators", when the language does not support that. Java and Delphi both do this for example. Imho I think eighter the language itself should support overriding operators (in this case the String "+"-operator) or there shouldn't be any messing with them.

Languages with "special situations" and "magic stuff" built into the compiler is bad for you :)

Btw: does BlitzMax support operator overriding? (got a vague memory that i might have seen something like that in the MiniB3D code)


Warpy(Posted 2008) [#11]
Would this be True then, if your code worked as you intend?

If String(jim) Print "I am a string"


You could interpret it that way I suppose, which you could make a good argument is the most consistent way of doing it, but what it boils down to is how the + operator works with strings.

If + is only defined between two strings, and the evaluator casts everything to a string before concatenating them, then yes, you'd have to end up with String(jim) <> Null. But if + is defined with overloading, like Mahan suggested:
string + string = string
string + (built-in number) = string+[string representation of number]
string + object = string+object.repr()


then you wouldn't necessarily have to say you can cast any object to a string.

Of course, this is the hidden overriding that mahan doesn't like, so it probably won't happen. If we could override operators ourselves then of course I wouldn't even need to post this. I suppose the reason I'm even posting this is that I just discovered you can add numbers to strings without casting, which I'm sure didn't work before, so if we've got that then why not objects too?

AlexO - yes, I'm trying to avoid typing .ToString() on everything.


Brucey(Posted 2008) [#12]
which I'm sure didn't work before

I think numbers to strings have always worked.

But interestingly, using + and using String.FromFloat() can have different results depending on your current locale. (ie. one is localized, the other is not - like dots, commas etc).

why not objects too?

Absolutely. It would be nice if it quietly used the ToString() method with string concatenation, since it is part of Object already. So long as casting to String still returned Null on a non-string Type.