« Towers of Hanoi FlashStickies 0.0.1 »

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]