Could we have a built-in Repr$() method?
BlitzMax Forums/BlitzMax Programming/Could we have a built-in Repr$() method?
| ||
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. |
| ||
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() |
| ||
Type 'ttypeid' into MaxIde and F1F1. It'll list the methods available with reflection which includes 'Fields' which are returned in a list. |
| ||
Ummm... isn't that what ToString() is suposed to do? If not, reflection is your friend as Mahan explains in his code sample. |
| ||
I was thinking the same, ziggy.. |
| ||
I was thinking the same, ziggy.. Phew... for a moment there I thought I was using it wrong... |
| ||
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. |
| ||
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. |
| ||
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? |
| ||
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) |
| ||
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. |
| ||
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. |