views:

373

answers:

5

Due to requirements outside of my control (don't ask, it's ridiculous) I need to create an AS3 class called 'Math' that references the Global AS Math class. So, for example:

package my.package
{
    public class Math
    {
        public static function pow( a:Number, b:Number ):Number {
            // How do I call the Global.as$Math#pow(..) function?
            return Math.pow(a,b);  
        }
    }
}

The code above is clearly wrong - results in infinite recursion. I'm not sure how to say that I want to delegate to the Global.as$Math class and not this Math class...

My current awkward solution is to delegate to another class (not named Math) that passes through to the Global Math class. Is there a better way to do this?

Thanks!

+1  A: 

Try using the AS3 namespace to refer to the AS3 Math object. Or your class could simply extend the Math object and it would automatically have all of the Math object's functionality without you having to rewrite all those wrapper functions.

apphacker
A: 

As a small follow up on apphackers reply, you can not simple extends the AS3 Math object and have all it's functionality as was suggeested. Static methods are lost when extending an object since they are statically tied to the object which defines them. Additionally you can't extends a class with the same name. You might have some success with the namespace solution however, though I'm not sure if it'll work with static methods, I'd be interested to see your results.

Tyler Egeto
Well there are two ways to extend an object in AS3, via extend and via the prototype. If you use prototype I think you do get the static methods.
apphacker
Sure, but you can't prototype the Math class, as far as I know.
Tyler Egeto
The Math class has a prototype object, all objects in ecmascript have the prototype object.
apphacker
ActionScript 3 has a special namespace called AS3 with duplicate functions that that take precendense over the functions defined on the prototype object. The functions in the AS3 namespace typically have higher performance because the runtime doesn't have to do a lookup on the prototype chain.
joshtynjala
A: 

Math is a special case in AS3 because really it shouldn't be global but it is. So it has no namespace as far as I can tell. The solution you came up with to route through another class is actually very clever. But you know that really the solution is to name the class Math2 or MathHelper or MathUtils rather than Math. Please tell me what the reason beyond your control is! The not knowing is killing me!!!

Iain
We've created a tool that uses a mix of antlr and bytecode analysis to generate AS3 from Java to speed areas of our development. Calls from the Java source to Java library functions require hand translation of the library function to AS3. For example, if I write java that refs the java.lang.Math class then I need an AS3 equiv java.lang.Math.as so that my generated AS3 code can still reference a class called java.lang.Math. Seems strange, but we've had much success with this approach.
tyler
wow good answer! just rout through a MathProxy class from your java.lang.Math class then.
Iain
+1  A: 

Save a static reference to the flash player Math object and use it throughout your static methods:

package test

{ import flash.utils.getDefinitionByName;

public class Math
{
  private static var _flashMath:Class = Class(getDefinitionByName("Math"));  
  public static function pow( a:Number, b:Number ):Number 
  {
            return _flashMath.pow(a, b);  
  }

}

}

akurtser
+6  A: 

Here is another way that popped into my mind after reading Josh Tynjala's post about how package in actionscript are just an abstraction layer over namespaces:

public class Math
{
  namespace globalNs = "";  
  public static function pow( a:Number, b:Number ):Number 
  {
            return globalNs::Math.pow(a, b);  
  }

}

The globalNs::Math.pow explicitly refer to the top level Math Class.

akurtser