Andreas Rønning wrote:
[snip]

*Yawn* here we go again, another new guy trying to understand this OBVIOUS concept that we've been through so many times already. I
can't believe he's bothering us with this again!

[snip]

Sorry, I was in a bad mood due to other circumstances, had just explained the very same thing in some other fora, and it's another monday morning... :)

(though I truely fail to see, how that is a scandinavian trademark?)

I just saw your posting:

2. What the hell is going on with "this" here

class ParseXML{
    private var xmlDoc:XML;
    private function handleXML(){
        trace(this);
    }
    function ParseXML(url:String){
        xmlDoc = new XML();
        xmlDoc.ignoreWhite = true;
        xmlDoc.onLoad = handleXML;
        xmlDoc.load(url);
    }
}

"trace this" in this case traces out the xml doc. Is this because onLoad = handleXML declares the scope of handleXML as being the xmlDoc? Sometimes the onLoad = functionReference; syntax weirds me out. I tend to go for the onLoad = function(){ more specific functionality here } method

And wanted to reply with an explanation - and the archives doesn't really give the mails their true position in the hierarchy with this many replies to replies and thus I really cannot see, if you've been given a proper answer.

Maybe I've misinterpreted your question from the above posting as stating a common question and not really asking it - are you? If so, disregard the below. Otherwise, consider the below my view of how things are actually interpreted. :)

"this"-references are dynamically evaluated. It is what i personally refer to as the "activating scope" and can as such be anything, that is pushed in to the function as the activating scope. The defining scope on the other hand cannot be changed.

Thus I can create a function that trace's "this" - no matter what "this" is:

var my_function:Function = function () { trace("this is "+this); }

I can then apply it to - say - a movieclip:

my_movieclip.some_function = my_function;
my_movieclip.some_function();

I can also invoke it runtime with the movieclip "pushed" in as the activating scope:

my_function.call(my_movieclip); // or .apply() - which ever suits you

The XML-class will internally call the onLoad-function as (pseudo-code):

private function __dataArrived():Void {
    // parse stuff, set status, do other stuff
    this.onLoad(this.status == 0);
}

Thus it will call the onLoad-function with the XML-object itself as the activating scope.

Some suggest it been worked around using a local property of the surrounding object as:

class Test {
        private var owner:Test;
        private var xml:XML;
        public function Test() {
                owner = this;
                xml = new XML();
                xml.ignoreWhite = true;
                xml.onLoad = handleXML;
                xml["owner"] = "local property of xml";
        }
        private function handleXML(success:Boolean):Void {
                trace("I am Test: "+(this instanceof Test));
                trace("I am XML: "+(this instanceof XML));
                trace("owner is Test: "+(owner instanceof Test));
                trace("owner is XML: "+(owner instanceof XML));
                trace("What is owner then: "+owner);
        }
        public function load(some_url:String):Void {
                xml.load(some_url);
        }
        private function toString():String {
                return "some Test-instance";
        }
}

But that will not work (as "owner" will be repaced with "this.owner" and will then point to the XML-instance-property and thus be a string).

Maybe someone suggests it being worked around using a static property (changing "private var owner:Test" to "private static var owner:Test"). Then it _will_ work (as "owner" is replaced with "Test.owner" when compiled), but then you can only have one instance simultanously - which may or may not be useful. At least not very pretty.

The defining scope can never be changed as explained. That is why the otherwise very used approach of:

class Test {
        private var xml:XML;
        public function Test() {
                xml = new XML();
                xml.ignoreWhite = true;
                var owner:Test = this;
                var callback:Function = handleXML;
                xml["owner"] = "local property of xml";
                xml["callback"] = "something not a function";
                xml.onLoad = function() {
                        callback.apply(owner, arguments);
                };
        }
        private function handleXML(success:Boolean):Void {
                trace("I am Test: "+(this instanceof Test));
                trace("I am XML: "+(this instanceof XML));
        }
        public function load(some_url:String):Void {
                xml.load(some_url);
        }
}

Now it works - and now "callback" and "owner" is read from the defining scope - and will always be the same. That is, we can "copy" this function to any object, invoke it using any activating scope, but the original reference to this particular instance of the Test-class and the corresponding method will be intact. Just for proof-of-concept two local properties are created in the XML-instance with similar names as the two variables from the defining scope.

And that's exactly what Delegate does.

I did notice, that the thread was moving in the direction of explaining, why the compiler added explicit "this"-prefixes to references to local variables and whether or not programmers should write these themselves when writing the classes. Well, to me it is a simple as: where should the interpreter read the variables from? They should be read from the defining scope, not the activating scope. Thus, of course "this." should be added. This gives the problem, that if you invoke the function with another activating scope (and thus IMO breaking simple AS2 best-practices), you lose the proper references.

I really don't think people should get too focused on the AS2-way of writing classes - it still works exactly as in the old AS1 days, and it will therefore have the exact same consequences using "this" - explicitly written or added by the compiler.

BTW: Having re-read the wonderful debate between Linus and Tanenbaum[1] just recently almost gave me a wish to start "flame-festing", but I really don't do that :)

[1]http://groups.google.dk/group/comp.os.minix/browse_frm/thread/c25870d7a41696d2/f447530d082cd95d

--
Morten Barklund - Information Architect - Shockwaved
Gothersgade 49, 4th floor - DK-1123 Copenhagen K, Denmark
Phone: +45 7027 2227 - Fax: +45 3369 1174
_______________________________________________
Flashcoders mailing list
Flashcoders@chattyfig.figleaf.com
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders

Reply via email to