July 30, 2003
traceObject
Ever get tired of debugging with the trace command and seeing [object Object] in the output window? Right in line with recursion discussion in my previous entry, I created a handy little function that will trace the entire contents of an object.
I'm sure someone else has done something like this before, perhaps even better than my approach. If so, post up a comment. Suggestions for improvement are also welcome.
Hopefully MTCodeBeautifier works this time.. I've seen inconsistent results when trying to post code. The code is in the extended entry (read more), and I apologize if the code is unreadable on the site here -- I'll provide a download link to an ActionScript file tonight sometime. If you have trouble reading it, view the source of the page and copy/paste into Flash.
UPDATE: Download the code here - traceObject.as - or use the download link on the front page of my weblog.
_global.traceObject = function(obj,outerChar,initialBlockDisplayed) { // if the variable we are tracing isn't an object, we can just // call the regular trace command and bail out. if (typeof(obj) != "object") { trace(obj); return; } // create a global variable to control the indenting in the // output window if (_global.$tabs == undefined) { _global.$tabs = ""; } // default the "outer character" of a container to be '{' // -- the only other choice here is '[' if (outerChar == undefined) { outerChar = '{'; } // initial block is used to signify if the outer character // has already been printed to the screen. if (initialBlockDisplayed != true) { trace(_global.$tabs+outerChar); } // every time this function is called we'll add another // tab to the indention in the output window _global.$tabs += "\t"; // loop through everything in the object we're tracing for (var i in obj) { // determine what's inside... switch(typeof(obj[i])) { case "object": // the variable is another container // check to see if the variable is an array. Arrays // have a "pop" method, and objects don't... if (typeof(obj[i].pop) == "function") { // if an array, use the '[' as the outer character trace(_global.$tabs + i + ": ["); // recursive call traceObject(obj[i],'[', true); } else { trace(_global.$tabs + i + ": {"); // recursive call traceObject(obj[i], '{', true); } break; case "string": // display quotes trace(_global.$tabs + i + ": \"" + obj[i] + "\""); break; default: //variable is not an object or string, just trace it out normally trace(_global.$tabs + i + ": " + obj[i]); break; } } // here we need to displaying the closing '}' or ']', so we bring // the indent back a tab, and set the outerchar to be it's matching // closing char, then display it in the output window _global.$tabs = _global.$tabs.substr(0, _global.$tabs.length - 1); outerChar == '{' ? outerChar = '}' : outerChar = ']'; trace(_global.$tabs+""+outerChar); } // some test code ref = _root.createEmptyMovieClip("test", 1); x = {a:"test", b:"test", c:[{innerobj:{innerinner:"asdf"},inner2:"asdas"}, "test"], d:ref}; traceObject(x); s="hjsadf"; traceObject(s); traceObject(sasd); traceObject({});

Comments
Thanks for this - it was exactly what I was looking for.
Here's some updated code for AS2 - it's just a static class wrapper around your basic code. I wasn't sure if the $ was an allowed character in AS2, so I global-search-replaced it away too...
pattu
/* converted from AS1 in Darron's blog:
http://www.darronschall.com/weblog/archives/000025.cfm
[code]
*/
class TraceObject {
static var tabs:String = "";
static function T(o) {
// Define the recursive function...
var T_ = function (obj,outerChar,initialBlockDisplayed) {
// if the variable we are tracing isn't an object, we can just
// call the regular trace command and bail out.
if (typeof(obj) != "object") {
trace(obj);
return;
}
// create a global variable to control the indenting in the
// output window
if (tabs == undefined) {
tabs = "";
}
// default the "outer character" of a container to be '{'
// -- the only other choice here is '['
if (outerChar == undefined) {
outerChar = '{';
}
// initial block is used to signify if the outer character
// has already been printed to the screen.
if (initialBlockDisplayed != true) {
trace(tabs+outerChar);
}
// every time this function is called we'll add another
// tab to the indention in the output window
tabs += "\t";
// loop through everything in the object we're tracing
for (var i in obj) {
// determine what's inside...
switch(typeof(obj[i])) {
case "object":
// the variable is another container
// check to see if the variable is an array. Arrays
// have a "pop" method, and objects don't...
if (typeof(obj[i].pop) == "function") {
// if an array, use the '[' as the outer character
trace(tabs + i + ": [");
// recursive call
T(obj[i],'[', true);
} else {
trace(tabs + i + ": {");
// recursive call
T(obj[i], '{', true);
}
break;
case "string":
// display quotes
trace(tabs + i + ": \"" + obj[i] + "\"");
break;
default:
//variable is not an object or string, just trace it out normally
trace(tabs + i + ": " + obj[i]);
break;
}
}
// here we need to displaying the closing '}' or ']', so we bring
// the indent back a tab, and set the outerchar to be it's matching
// closing char, then display it in the output window
tabs = tabs.substr(0, tabs.length - 1);
outerChar == '{' ? outerChar = '}' : outerChar = ']';
trace(tabs+""+outerChar);
};
// So call it..
T_(o);
}
}
[/code]
Posted by: pattu at February 7, 2004 12:39 PM