dzimney
dzimney

Reputation: 552

Conflicting Scope: Global Functions and Class Methods of the Same Name

My question deals directly with ActionScript 3, although it could possibly appear in other languages.

Consider the global trace function found in AS3. Calling the method requires no imports and is globally available from all classes.

class A {

    public function A() {
        trace("Hello, A!"); // Hello, A!
    }

}

Now, what if I create my own class method of the same name? In AS3, if I have a class method trace and then make a call to trace elsewhere in my class, the call is made to the class method over the global function. Essentially, I've blocked my ability to call the global trace method.

class B {

    public function B() {
        trace("Hello, B!"); // no output
    }

    public function trace(s:String):void {
        // do something else.
    }

}

Now, I know the obvious answer is to say, "don't create a class method called trace." But what if I'm unaware of the existence of the global trace function? Or what if I have a desire to "override" or "block" the global function? Is doing so bad programming? Or is this just another example of how AS3 is a poor object oriented language?

Upvotes: 3

Views: 837

Answers (4)

You Ziwei
You Ziwei

Reputation: 21

import flash.uitls.*;

then you can use

(getDefinitionByName('trace') as Function)('Global trace.');

Upvotes: 2

Stefan Dragnev
Stefan Dragnev

Reputation: 14473

An alternative method would be to change the place where the name binding to the global identifier happens, like with the following wrapper class:

class B {
    public function B() {
        Globals.global_trace("Hello, B!"); // delegates to global trace()
    }
    public function trace(s:String):void {
        // do something else.
    }
}

class Globals {
    public function global_trace(...args) {
        // class B's identifiers are now irrelevant for the name lookup
        trace.apply(null, args);
    }
}

A more localized approach would be to rebind the global symbol before hiding it:

private static var _trace:* = trace; // rebind global trace

public function trace(...args) {
    _trace.apply(null, args);
}

Upvotes: 0

Patrick
Patrick

Reputation: 15717

If your function trace was not public you could using the public namespace to call the original function :

class B {
    public function B() {
        // call the trace function that is defined in the public namespace
        public::trace("Hello, B!"); // output "Hello, B!"
    }

    // here the function is protected so not into the public namespace
    protected function trace(s:String):void {
        // do something else.
    }
}

Upvotes: 1

scriptocalypse
scriptocalypse

Reputation: 4962

"But what if I'm unaware of the existence of the global trace function?"

I'd see this more as an indication that you haven't yet done due diligence in your language research than as a fault in the language itself. There are very few top-level names and keywords in AS3, and I think it's fair to say that if you're interested in learning a language you should at least familiarize yourself with that top level.

Upvotes: 0

Related Questions