The _root of all evil…

Whenever it’s late and I’m trying to fix someone elses code, which I know next to nothing about, and that code uses loads of references to _root.someMadInstanceName.someFunction(), a certain set of Slayer lyrics comes to mind…

“The root of all evil is the heart of a black soul,
A force that has lived all eternity.
A never ending search for a truth never told,
The loss of all hope and your dignity.”

I must admit that I hate _root. It’s almost always used to get around some crazy scope problem or other, and it usually makes it really hard to figure out what’s going on in someone else’s code when it uses _root.something() all over the place. For me, using _root is like admitting failure.

However, this afternoon,I was asked if I could think of a way to somehow extend _root in an AS2 class, so _root methods could be safely used in AS2 without having to put a extra movieclip in the flash display tree just to hold the class. What I came up with was the idea of creating an instance of class object in _root, and using __resolve to redirect the calls to _root into it. Check this out:

In the root timeline of your movie:

import MyMuchBetterRoot;
betterRoot = new MyMuchBetterRoot(this);

__resolve = function (name) {
        //if you wanted to monitor all the calls to _root, you could do so here
	trace("resolving "+name);
        var f:Function = function () {
            betterRoot[name].apply(this,arguments);
        };
   return f;
}

In the class MyMuchBetterRoot.as:

class MyMuchBetterRoot extends MovieClip{

        //pass in and store a reference to _root, in case
        //you need to get to it later
       private var rootRef :MovieClip;

       public function MyMuchBetterRoot(rootRef){
               trace("I am a much better root than "+rootRef);
               this.rootRef = rootRef;
       }
       //random test method
       public function helloWorld(foo, bar){
               trace("Hello World");
               trace("foo="+foo);
               trace("bar="+bar);
               rootRef.foo = foo;
               rootRef.bar = bar;
       }

        public function __resolve(name){
        //if a method doesn't exist in the class, trace out an error
         trace("ERROR:Function "+name+" does not exist.");
        }

}

You then move all the _root methods into MyMuchBetterRoot.as, and let the rest of the movie call non-existant functions on _root. These calls will automatically get re-routed to the class, or, if they’re referring to functions that don’t exist, you’ll get an error trace, with the name of the function you’re calling.
This means you get the best of both worlds - you can have methods on the root, but still have them in an AS2 class, and you can also track those pesky calls to _root, and possibly figure out where they’re coming from. Although if I can, I usually avoid using _root altogether, I’ll definitely be using this method again.

Leave a Reply

You must be logged in to post a comment.