Customizing toString()

Written on September 8, 2008 – 2:15 am | by sascha |

When writing classes for a framework I usually put a custom toString method into important classes so that debugging becomes easier. Normally they would go like something along the lines of:

override public function toString():String {
	return "[ClassName]";
}

… Sometimes adding properties to the returned String that give back information about the class, e.g.

override public function toString():String {
	return "[ImageClass, size=" + _size + "]";
}

But writing them rigid like that is a disadvantage when you decide later to refactor class names. Admittedly it’s also not a very elegant way so I got the idea to take the class name that is returned by getQualifiedClassName(). The only problem is that getQualifiedClassName not only provides the type name but also the whole package String of the class. Regular Expressions to the rescue! After twiddling around with them for a while (I’m by no means a RegExp expert) I got my toString method into the shape that I desired:

override public function toString():String {
	return "[" + getQualifiedClassName(this).match("[^:]*$")[0] + ", size=" + _size + "]";
}

This way it matches the String returned by getQualifiedClassName with the Regular Expression [^:]*$ which checks from the right end for an arbitrary text up to the first occurring colon, but without including the colon. Taking the first element of the Array returned by match() and you got what you need!

A nice way of using this is when writing abstract classes that contain the toString method and any subclass can use that toString method without the need to override it … that is of course unless you want ot add other output information.

  1. 9 Responses to “Customizing toString()”

  2. By Steven SacksNo Gravatar on Sep 8, 2008 | Reply

    That’s some smart code right there. I’m going to include it in the next release of the Gaia framework and really all my work from now on. Thanks for the great tip!

  3. By saschaNo Gravatar on Sep 8, 2008 | Reply

    Thanks Steven! I improved the toString method a little more today … I’m using a base Class named BasicClass from that other classes can extend if they need toString. The BasicClass then gets the following:

    public function toString(...args):String {
    	var s:String = "";
    	for each (var i:String in args) s += ", " + i;
    	return "[" + getQualifiedClassName(this).match("[^:]*$")[0]
    	+ s + "]";
    }

    That way you could add any number of additional debug information comma-separated as an argument.
    Sub-Classes then just need something like for example:

    override public function toString(...args):String {
    	return super.toString("path=" + _path, "size=" + _size);
    }

    So only the BasicClass needs to have the getQualifiedClassName… code in it.

  4. By Joa EbertNo Gravatar on Sep 11, 2008 | Reply

    Hey, besides the (expensive) RegExp you could also do this:

    var name: String = getQualifiedClassName(obj);
    name = name.substring( name.lastIndexOf( ‘::’ ) + 2 );

  5. By saschaNo Gravatar on Sep 11, 2008 | Reply

    Hi Joa, yes I had that method in mind too. the question is: what is more expensive? substring() or match()? I keep hearing from all sides that regExp’s are more fast, powerful and generally being the next best thing to sliced bread. So I went with that. ;)

  6. By tonyNo Gravatar on Oct 4, 2008 | Reply

    Hey, that is some great and helpful stuff. Does just what I needed. I will put it to immediate use and thanks. Bythe way, I would think a search for text in a string would have to be faster than the regular expression, but I don’t think performance-wise anyone will notice either way. Thanks again and take care.

  7. By saschaNo Gravatar on Oct 4, 2008 | Reply

    hey tony. sure you could do that too with lastIndexOf as Joa said … but where would be then fun in that?! … i.e. I just wanted to make myself more familiar with RegExp’s. Then again tostring methods aren’t the kind of stuff that need to provide a lot of performance, but hey, choose what you like. :)

  8. By tonyNo Gravatar on Oct 4, 2008 | Reply

    You are right that regexps are more fun and also very handy to know. Anyway, I had to find out if there was a performance difference and ran a test. As expected, because the regular expressions are much more powerful than a plain search, they are also much slower. I ran each way in a tight loop 10,000 times and the regular expression method takes 120 times longer. If you are only doing a few dozen regex matches, no one would notice, but where performance is key and the matching is simple, avoid regex. They are mostly useful for very complex expressions that you cannot easily search for using simple methods. Anyway, great work on the toString override. I needed it and would never have come up with that myself.

  9. By saschaNo Gravatar on Oct 4, 2008 | Reply

    Thanks for the info tony! I wasn’t sure but it’s good to know that!

  10. By igorNo Gravatar on Oct 16, 2008 | Reply

    Object.prototype.toString = function() {
    var r:String = “[" + getQualifiedClassName(this).match("[^:]*$”)[0];
    if (this.name)
    r += ” name =”" + this.name + “” “;
    r += “]”
    return r;
    }

    Object.toString() is dynamic so it works for most of classes

Post a Comment

Welcome to H1DD3N.R350URC3!

These are the adventures of a random guy trying to be an independant game developer, utilizing ActionScript for programming and talking abouting gaming and nonsense in general.

Need any news feed?

 Main Feed (contains all categories), Dev Feed, Design Feed, Audio Feed, Gaming Feed, Miscellaneous Feed
Find entries: