The first real programming language I ever used was HyperTalk on Macintosh computers almost 5 years ago. It was a language that was compiled once when the code is first executed. Today, I use modern languages like C++, Objective C, Java and ActionScript 3 which provide much better performances thanks to the use of compilers.
We all take compilers for granted, pressing save/compile just to see if what we are doing makes sense. I know that while I am coding, I subconsciously type a line and press compile while I write the next line of code. I should point out that I am not a compiler expert. Nor do I have any knowledge of how they work their magic.
Recently(by recent I mean 2 months ago), I discovered a very important lesson about these dynamic languages while I was doing some Flex web development using a caingorm micro-architecture. I was surprised to find that the dynamic goodness of ActionScript 3 meant that I was getting the strangest runtime error message I had ever seen. Here is what the situation was…
- The runtime error message said something along the lines of the class package.ClassName couldn’t be found within the SWC.
- The .as file existed with the correct class name and package/directory path.
- The package declaration in the class definition was correct.
- The object that I was receiving from the server was mapped to my local class on the server to remove the need to serialise the object myself.
- The call-back function(responder) from the server was receiving a vanilla “Object”.
- Thanks to my type a little and run/compile the code policy, I was testing the web service to see if I was getting the correct data and that the server had been configured correctly, particularly in relation to the class mappings.
You can see that I did my part as developer to make it work. Or did I really? Apparently not! The way that the AS3 compiler works[from what I can gather] is it only tries to compile and bundle a Class if it is ‘required‘ within the final application. The keyword here is obviously ‘required‘. What do I mean by required? The way that the way the flex compiler works is it compiles and includes a class in the final SWC only if you create a instance of it or use it as a argument for an function because its code is then seen to be ‘required’(FYI, other languages such as C/C++ take this same laziness approach with functions too). Take the following (calorie counting application? :S) into consideration which shows dependencies for its classes:
When you compile the Main function, it will require the ArrayClass so it can store many Recipe objects. Also, Recipe will require an ArrayClass to store many Ingredient objects. Your project might even contain another Fruits class which (currently) isn’t required for the binary to be complete so its bytecode isn’t included in final output. To make compiling faster, the Fruits class wouldn’t even be looked at by the compiler.
So why was the problem happening and how did I fix it? Well, the problem was happening because I was never creating a object of the class or declaring its use as a function parameter. The fact that I was depending on the server side to type the object for me meant that when I received my object, the runtime was unable to map it to my local class because it wasn’t compiled into the SWC. In relation to the example above, this is a Fruits instance being sent to our running application over a network connection and the runtime is unable to find Fruits in its class list. You can imagine, the fix to this would be to create a single instance of the class-in-question so that you ‘force’ the compiler to include the class in its binary.
I hope you have all learnt something more about how compilers behave when executing. If you have any questions about this or other weird compiler issues, as usual gimme a shout in the comments.