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".
Josh,
This is really cool. Thanks for sharing.
–Daniel
Very interesting discovery. I had noticed the ::, but like you hadn’t given it a second thought.
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…
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:
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.
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.
Interesting discovery, cool to declare class from an xml then.
Thx for sharing,
S.
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.
Great discovery, used this in my answer to a stackoverflow question.
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
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
Yes, you’re right, karfau. public/protected/private/internal are all namespaces. I think your code should look like this:
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
privatenamespace 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
privatejust because it sounded like a fun blog post. That sort of exploration actually led to the package/namespace relationship I revealed here.