Pushing the boundaries

…couldn’t be any simpler!

ActionScript code tricks

Posted by vijayram on January 26, 2007

Continuing this topic, today I shall discuss the benefits of CONSTANTS. I have seen several programmers use it in AS 2.0, but with AS 3.0 to me, it all made sense.

CONSTANTS are all uppercase and spaces converted to underscore. (eg: SERVER_NAME=”god”;)
Values assigned to CONSTANTS do not change as it implies. Declaring a CONSTANT is rather straight forward as declaring a variable with the var keyword.
public static const SERVER_NAME:String =”god”;

In ActionScript 3.0, the one place you will always encounter CONSTANTS are Events. It is best code of practice to use static CONSTANTS property of the Event class.(eg: addEventListener(Event.ENTER_FRAME, onEnterFrame); )

Lets just understand why we require to use the static CONSTANTS, as supposed to using just “enterFrame”. ActionScript 3.0 is a dynamically typed language and also supports compile-time type checking using the “strict mode”. I could type the above Event as follows, which is still valid – addEventListener(“enterFrame”, onEnterFrame);
But what if I were to type it as follows – addEventListener(“enterFame”, onEnterFrame);

I would definitely have “entered Fame” but for all the wrong reasons. The above code would be still compiled by the compiler though no errors will be reported. I would be spending unnecessary time to debug this. To avoid any such mistakes it is better to use the CONSTANT property of the class. How to we create one for our class?

This brings us to another topic of Enumerations. Enumerations are custom data types that you create to encapsulate a small set of value. ActionScript 3.0 does not support a specific enumeration facility like C++ or Java, however you can create this behaviour using classes and static CONSTANTS.

For example, a visitor to a web-page has a choice of language. The LanguagePreference class will use an enumeration PrefLanguage to store a set of language values.
public final class PrefLanguage {
public static const ENGLISH:String = “english”;
public static const FRENCH:String = “french”;
}

Now you can access the enumeration values as follows:
var myLanguage:LanguagePreference = new LanguagePreference();
if ( myLanguage.Language ==PrefLanguage.ENGLISH){
…….
}

The advantage of using the above method is that your code is type-safe, thereby catching errors at compile time. The only disadvantage that I can think of is the need for an additional class to be written to hold your enumeration types.

Advertisements

4 Responses to “ActionScript code tricks”

  1. Pete said

    Thanks for the well written explanation. I have a design question tho, would you use these on something that implements an interface? Would that mean you’d provide it the means of a static getter?

  2. Edgar said

    Your enum example is really good, and it’s definately one that I use frequently in languages like ActionScript 3.0 and even earlier versions of Java. I would just like to mention another technique that I learned from Steve McConnell’s Code Complete.

    While your enum example has some type safety, it is not completely type safe. For example you may write a function that is expecting a string passed in based on the strings you enumerated PrefLanguage class. You would write a function like the following:

    public function MyFunc(language:String):void {

    }

    The problem is pretty clear. You can pass any string into the function and the compiler will not catch it. An alternative to your enum strategy is to write code like the following:

    public final class PrefLanguage
    {
    public static const French:PrefLanguage = new PrefLanguage();
    public static const English:PrefLanguage = new PrefLanguage();
    }

    By defining your enum this way you may now write your function to look something like this:

    public function MyFunc(language:PrefLanguage):void {
    if (language == PrefLanguage.French) {
    }
    else if (language == PrefLanguage.English) {
    }
    }

    By using the above approach you gain the extra type safety that only PrefLanguage values may be supplied. There is one glaring issue with this technique, and that has to do with the inabality to make constructors private in ActionScript. It is still possible for a programmer to create a PrefLanguage instance other than the one’s defined within the class. Ideally the constructor would be made private to avoid this problem. While the ability to instantiate non-defined PrefLanguage instances is a real problem this is still the technique I prefer for emulating enum functionality. Please note that if you want to be able to have an underlying int with this technique you need only declare it as a data member, for example:

    public final class PrefLanguage
    {
    private var _value;

    public function PrefLanguage(value:int):void {
    _value = value;
    }

    public static const French:PrefLanguage = new PrefLanguage(0);
    public static const English:PrefLanguage = new PrefLanguage(1);

    public function get Value():int {
    return _value;
    }
    }

  3. Wow, Edgar, that is a great solution! In C# (and maybe in Java as of 1.5?) we have an enum class which does just that.

    To make constructors private, why call the value “value?” It makes no sense. I do this

    const constructorKey:String = “dsadñlkfjdsafkñldasf”;

    public function PrefLanguage(doNotCallThisConstructor:String):void {
    if (constructorKey.equals(doNotCallThisConstructor))
    throw new Error(“Don’t call this constructor, use the enums!”);
    }

    (sorry if the code has syntax errors, I’m just typing it here from memory).

    Anyway, love your enum solution.

  4. Here’s my final example. It’s the same, but a little different.


    package
    {
    public class SoloState
    {
    private static const constructorKey:int = 5612584;

    public static const SOLO_ON:SoloState = newInstance;
    public static const SOLO_OTHER:SoloState = newInstance;
    public static const NORMAL:SoloState = newInstance;

    public function SoloState(dontInstantiateMe:int)
    {
    if (dontInstantiateMe != constructorKey)
    throw new Error("Sorry, private constructor");
    }

    private static function get newInstance():SoloState {
    return new SoloState(constructorKey);
    }

    }
    }

    Dan
    http://www.theSATfaq.com
    Expert answers to questions about the SAT

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: