In .NET, every object responds to .toString which is a generally good idea. Unfortunately, this is rather uninformative for collections which only return their type, not their contents. A list of three ints returns "System.Collections.Generic.List`1[System.Int32]"
The .toString method is used by the Cobra "print" statement and also in string substitution such as "[x], [y]".
In Cobra, there is also CobraCore.toTechString(obj) which returns the more useful "List<of int>[1, 2, 3]".
This utility method is the basis for the "trace" and "assert" statements where its verbose nature helps with debugging.
But more than one person has expressed that they would like "print list" to produce "[1, 2, 3]" instead of what .toString and CobraCore.toTechString produce. Likewise with dictionaries and sets.
So here is my plan:
(a) Cobra will use a new CobraCore.toPrintString(obj) for both "print" statements and string substitution.
(b) Cobra will continue to use CobraCore.toTechString(obj) for "assert" and "trace".
(c) .toPrintString and .toTechString will actually be method references (aka delegates) assigned to .toPrintStringDefault and .toTechStringDefault which are the real methods. You can reassign the delegates if you want to customize the output of your program.
(d) .toPrintStringDefault will produce slimmer, more friendly output than .toTechStringDefault. Unlike .toString, it will show the contents of collections such as "[1, 2, 3]" and "{'a': 1, 'b': 2}".
(e) Finally, through the magic of extensions, .toPrintString and .toTechString will be added to System.Object for convenient, OO-style access.
After these changes, the default output for "print" will be more useful and palatable, and both types of output will be amenable to customization by you, the programmer.
Feel free to comment.
Forums
Converting objects to strings
19 posts
• Page 1 of 2 • 1, 2
Re: Converting objects to strings
Excellent.
I was just going to start a bit of a posting/rant on this very subject - how useless the default toString display is for adhoc debug/trace output and what
could be done about it.
I implemented a variant of toTechString ( toXString) that emits basically the same string output without the embedded type info and had started using it explicitly on
print statements for collections. The next step was to munge the print syntax some and get it called implicitly (or at least more conveniently than explicitly wrapping each collection
in a CobraCore.toXString() call.
(a) and (b) address all of that simply and conveniently (c) and (e) are additional (v tasty ) icing.
Damn good plan.
I was just going to start a bit of a posting/rant on this very subject - how useless the default toString display is for adhoc debug/trace output and what
could be done about it.
I implemented a variant of toTechString ( toXString) that emits basically the same string output without the embedded type info and had started using it explicitly on
print statements for collections. The next step was to munge the print syntax some and get it called implicitly (or at least more conveniently than explicitly wrapping each collection
in a CobraCore.toXString() call.
(a) and (b) address all of that simply and conveniently (c) and (e) are additional (v tasty ) icing.
Damn good plan.
- hopscc
- Posts: 632
- Location: New Plymouth, Taranaki, New Zealand
Re: Converting objects to strings
For your amusement heres toXString code.
Its basically a lightly twitched toTechString implementation prior to refactoring to remove dup code.
Its basically a lightly twitched toTechString implementation prior to refactoring to remove dup code.
- Attachments
-
- toXString.patch
- Not a patch file cs code and notes
- (5.32 KiB) Downloaded 594 times
- hopscc
- Posts: 632
- Location: New Plymouth, Taranaki, New Zealand
Re: Converting objects to strings
Thanks. The middle of this week in pretty busy for me, so I'll be looking at patches later in the week, maybe on Saturday. There is this one, the slicing one and the escaped left bracket one.
- Charles
- Posts: 2515
- Location: Los Angeles, CA
Re: Converting objects to strings
Oops should have said
- thats not a patch file - just the code for toXString ( you'll probably find it familiar ) and some untested/uncompiled code+notes for
refactoring toTechString and ToXstring.
the ToXString codes does do just about everything I needed for collection display handling SFAIKATM..
You can have the patches for all the changes if you want them but your plan and approach is different and
will go way beyond what I did.
- thats not a patch file - just the code for toXString ( you'll probably find it familiar ) and some untested/uncompiled code+notes for
refactoring toTechString and ToXstring.
the ToXString codes does do just about everything I needed for collection display handling SFAIKATM..
You can have the patches for all the changes if you want them but your plan and approach is different and
will go way beyond what I did.
- hopscc
- Posts: 632
- Location: New Plymouth, Taranaki, New Zealand
Re: Converting objects to strings
Should also have said I did that cos the web page upload attachment thingy isnt taking files with .cs extensions
- hopscc
- Posts: 632
- Location: New Plymouth, Taranaki, New Zealand
Re: Converting objects to strings
Thanks for the note. For the future, I've added .cs to the list of allowed extensions. You don't need to reattach just for that.
- Charles
- Posts: 2515
- Location: Los Angeles, CA
Re: Converting objects to strings
I have a really good start on this. I forgot to mention that the new version will be pure Cobra and come with inline test cases, of course.
I liked your idea of the delegate parameters for converting strings and types to strings, but then I ended up adding more and more for things like enums and last case objects. It's getting to be too much, so it looks like I'll refactor the whole thing into classes. There will be a common base class and two specific subclasses for ToPrintString and ToCobraString. The run-time will have instances of these which you can replace if you like and thereby customize the output of your program. You would make your own subclass and override the appropriate methods.
Cobra already does something similar for the "trace" statement by having a Tracer class and a default instance at run-time that you can modify via properties, or replace wholesale.
I also have a fuzzy idea in the back of my head for a data driven approach. Something like a list of types that map to delegates that do the string conversion. Then its just a matter of looping through that list looking for "if x.getType.isSubclassOf(t)" and invoking the delegate. A list is needed for precedence (IList is more specific than IEnumerable), but a dictionary cache could probably speed it up.
I'll have to give it some more thought.
I liked your idea of the delegate parameters for converting strings and types to strings, but then I ended up adding more and more for things like enums and last case objects. It's getting to be too much, so it looks like I'll refactor the whole thing into classes. There will be a common base class and two specific subclasses for ToPrintString and ToCobraString. The run-time will have instances of these which you can replace if you like and thereby customize the output of your program. You would make your own subclass and override the appropriate methods.
Cobra already does something similar for the "trace" statement by having a Tracer class and a default instance at run-time that you can modify via properties, or replace wholesale.
I also have a fuzzy idea in the back of my head for a data driven approach. Something like a list of types that map to delegates that do the string conversion. Then its just a matter of looping through that list looking for "if x.getType.isSubclassOf(t)" and invoking the delegate. A list is needed for precedence (IList is more specific than IEnumerable), but a dictionary cache could probably speed it up.
I'll have to give it some more thought.
- Charles
- Posts: 2515
- Location: Los Angeles, CA
Re: Converting objects to strings
Ideally of course you;d just like to invoke something on the object directly ( like toString() )
Hmm, Is the extension support sufficient to just add an extension method to the classes/interfaces that need the special ToTechString/ToPrintString handling.
(IEnumerable, ILIst(?), IDictionary, enum?, ..) - is there a small enough set of them?
This could contain the conversion to string code or return some sort of dispatch tag indicating which actual delegate to call...
The handler then just becomes an invocation or invocation and dispatch
if that method lookup fails or is non existant then fall back to subclass/type interrogation and delegate for the simple class cases ....
(For user defined collection classes the user can then choose to implement their own desired TechSting/DisplayString rep as needed
similarly as is done for toString )
Hmm, Is the extension support sufficient to just add an extension method to the classes/interfaces that need the special ToTechString/ToPrintString handling.
(IEnumerable, ILIst(?), IDictionary, enum?, ..) - is there a small enough set of them?
This could contain the conversion to string code or return some sort of dispatch tag indicating which actual delegate to call...
The handler then just becomes an invocation or invocation and dispatch
if that method lookup fails or is non existant then fall back to subclass/type interrogation and delegate for the simple class cases ....
(For user defined collection classes the user can then choose to implement their own desired TechSting/DisplayString rep as needed
similarly as is done for toString )
- hopscc
- Posts: 632
- Location: New Plymouth, Taranaki, New Zealand
Re: Converting objects to strings
The problem is that I don't control the base class library and the "extend" feature is a compile-time phenomena. I've played around with the idea of registering extensions with the Cobra run-time so they can be accessible to Cobra's dynamic binding, but that isn't much different than the "type --> delegate" map I described above.
However, you reminded me that the last ditch step should be to check for a "toTechString" or "toPrintString" via reflection, before invoking "toString".
Of course, most people won't even care about these details. They only come up if you're going to customize the output or you're simply interested in the implementation.
-Chuck
However, you reminded me that the last ditch step should be to check for a "toTechString" or "toPrintString" via reflection, before invoking "toString".
Of course, most people won't even care about these details. They only come up if you're going to customize the output or you're simply interested in the implementation.
-Chuck
- Charles
- Posts: 2515
- Location: Los Angeles, CA
19 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 6 guests