Packages are actually namespaces in ActionScript 3

by Josh Tynjala

Have you ever looked at the returned value of the function flash.utils.getQualifiedClassName() and wondered why it includes :: between the package and the class name? For example, if you pass in a MouseEvent instance, you'll get the string value "flash.events::MouseEvent". The first time I tried it, I expected to receive "flash.events.MouseEvent" with a . because that's how you reference a packaged class in an import statement. I always thought the difference was a little strange, but I just shrugged and went about my business. Today, though, my mind must have been feeling a little extra clever than ususal because it suddenly dawned on me: you use :: as an operator in ActionScript 3 to access a namespace.

With one simple test, it became unquestionably clear that packages in ActionScript 3 are really an abstraction built on top of namespaces. Try running the following code using the Flex SDK or the Flash authoring tool:

namespace flash_events = "flash.events";
trace( flash_events::MouseEvent ); //output: [class MouseEvent]

No import needed!

I imagine this has ECMAScript 4 roots. In general, many of the OOP features of AS3, like class and package syntax, are considered syntactic sugar. How can AS3 developers benefit from this knowledge? I have no idea, but it's one of those discoveries that whispers, "someday, you may need me".

About the Author

Josh Tynjala is an indie game developer, entrepreneur, Flash and Flex mercenary, and bowler hat enthusiast.

Discussion
  1. Josh,

    This is really cool. Thanks for sharing.

    –Daniel

    posted by Daniel Gasienica on 05.13.2009
  2. Very interesting discovery. I had noticed the ::, but like you hadn’t given it a second thought.

    posted by Ben Dalton on 05.13.2009
  3. Great post. I use package and class lookup a lot when doing reflection in Flash. I really love creating classes defined from XML. As you pointed out there is really nothing “interesting” you can do with this knowledge but understanding the principles behind how things work is a critical part of being a good developer. Thanks for the info…

    posted by Jesse Freeman on 05.13.2009
  4. Yep – I was working with XML in Flex/AS3 just yesterday, taking contents from two XML objects and creating a third one, and noticed it added a namespace attribute automatically referencing the class that was building it:

    xmlns="com.model:NexusModel"
    
    the xmlns attribute was added by AS3 - not me.  The code that generated it looks liked this:
    
    finalXML.modules.module[thisId] = "";
    finalXML.modules.module[thisId].@title = moduleItem.LinkTitle;

    I thought that was interesting. Not exactly useful on this project - it adds bloat to the file - wonder if there is a setting to turn that off, but not a big deal. Cool feature though. So because of this, I'm thinking yeah, it may indeed have E4X roots.

    posted by Jason Merrill on 05.13.2009
  5. Nice article.

    You can actually use those namespace references as _variables_ and selectively switch between sets of values.

    (assuming you have a class named LanguageTable with variables in the right namespaces)
    namespace current_language = “english”;
    trace(LanguageTable.current_language::NoFileError); // “File not found!”
    current_language = “german”;
    trace(LanguageTable.current_language::NoFileError); // “Datei nicht gefunden!”

    Essential ActionScript 3.0 goes into some detail on this. Definitely worth a read. Very cool stuff.

    posted by Ben Garney on 05.13.2009
  6. Interesting discovery, cool to declare class from an xml then.

    Thx for sharing,

    S.

    posted by Sakana on 05.13.2009
  7. How funny! I just made the same discovery about the change from “.” to “::” yesterday.

    Unlike you, I was just distressed. It took me an hour to sort out why my app wasn’t working.

    posted by Ian on 05.14.2009
  8. Great discovery, used this in my answer to a stackoverflow question.

    posted by Almog Kurtser on 05.16.2009
  9. Great post. I love the idea of assisting developers so they only seeing the methods via intellisense (of Flex Builder) for methods they need to see. I created a new demo to show that off. http://www.blog.rivello.org/?p=422

    posted by Samuel Asher Rivello on 06.01.2009
  10. this goes even further:
    even public, protected and private are just namespaces:
    usage from outside of the class would look like this:

    var myref:* = object.(private::_privateObjectProperty);

    wich compiles fine but (fortunately) throws a Type-Error when running:
    TypeError: Error #1123: Filter-Operator not supported for type [type of object].

    hopefully there is no way to get around this limitation (espacially for private and protected). I saw code-examples that changed properties of Flex-Components this way where those properties lay in the mx_internal-namespace.

    karfau

    posted by karfau on 12.10.2009
  11. Yes, you’re right, karfau. public/protected/private/internal are all namespaces. I think your code should look like this:

    object.private::_privateObjectProperty

    Parentheses are used for E4X filtering, so they’re in no way usable here.

    However, that won’t work. I’ve spent a lot of time trying to hack namespaces to see just what I can get away with. It’s not possible to access a private member outside it’s class. The private namespace is specifically defined with a different value in each class (on the global object, which is also a different object for each class file). So class Apple’s private is not the same as class Orange’s private.

    In fact, it appears that the virtual machine has some extra protection. With the right function calls, you can trace the string representation of a particular class’ private namespace. However, if you try to define it in another class, it still won’t let you access something that’s private. Likewise, if you assign the private namespace to a variable and return it in a function call from the owning class to another class, it’s still useless for accessing the private members. This may be AS3 traits in action, or the separation of global objects in classes, or maybe defined by the language itself. Regardless, I’ve spent hours trying to hack private just because it sounded like a fun blog post. That sort of exploration actually led to the package/namespace relationship I revealed here.

    posted by Josh Tynjala on 12.10.2009
  12. Josh’s last post is not strictly true (that you cannot access private member variables outside of the defining class). If you are able to obtain the right Namespace object, you can create a QName, and subscript the object via that to access any arbitrary property. The key issue is obtaining the actual Namespace object for a given class, which may not be possible in direct literal code. However….

    One trick you can use is to use the getMemberNames() top level function in the flash.sampler package to retrieve an object that can be used to iterate over all of the member variable names (private or not) in a given object [you must be in the debug player for this to work, and there are other conditions as well]. Iterating over the returned object with a “for each” loop yields a series of QName objects that can be used via the subscript notation to access the value of the corresponding property, and this includes private member variables.

    posted by James Bond on 07.17.2010
  13. James, flash.sampler doesn’t really count because it only works in the debug player. For the record, I was able to pass a private namespace object outside a class, but it only worked inside the class. I think I got a runtime error when I tried using it outside.

    posted by Josh Tynjala on 07.17.2010
  14. Josh, I think the statement that was made was that it was absolutely impossible to access private member variables outside of their defining class. I have provided a counter example showing it is doable; obviously there must be some limitations to it for helping to ensure the integrity of the application once its deployed. I have also described a means by which it can be accomplished. Did you try using my method to access the member variables outside at all?

    posted by James Bond on 07.22.2010
  15. James, I confirmed that the QName returned from flash.sampler.getMemberNames() can be used to access the value of a private variable. I am unable to construct my own QName, with the same uri and localName, that is able to do the same thing, even in the debug player and in the same running SWF. There’s some magic in the one returned from getMemberNames().

    The meaning of my original statement was that you can’t access private members in a production environment. I’m sorry for the confusion.

    posted by Josh Tynjala on 07.22.2010
  16. Right — I have experienced the same thing (can’t synthesize the namespace or QName objects that getMemberNames returns). There is one line in the docs that hints that the “special” namespace that is used to get at the private and otherwise inaccessible member variables is not utterable. I’m using this technique right now to do some object reference graph traversals, so it’s highly beneficial in specific circumstances.

    posted by James Bond on 07.23.2010
Share Your Thoughts

To display code in comments: <pre>Code here. May be multiline. Format XML with &gt; and &lt; entities.</pre>

Some HTML allowed in comments: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>