Thursday, June 2, 2011

Why semicolons?

It seems that most of my ActionScript code can easily go without semicolons so i leave them out. What do you think about it?

The art of possible

Something that all over sudden appeared in my mind. I'm not sure what to make of it. Maybe i'm jut getting crazy ;)

private function log(message:String):Function
return arguments.callee

private function main() : void


Tuesday, February 1, 2011

My new repository for snippets

I created a repo for all the little snippets, which i collect over time. You can find it here: If you want to get informed, when something changes in the repo, you should "watch" it.

Wednesday, January 26, 2011

Using FlexUnit with locales other than the ones provided by FlashBuilder 4

Today i took some time to find out, why the integrated FlexUnit support doesn't work, if your project has a locale other than the ones provided by FlashBuilder.

One of my last Flex projects was for the danish web market. Therefore it used the danish locale. Of course we wrote a lot of unit tests to verify our code. Unfortunately the integrated support for FlexUnit didn't work with the danish locale. It always gave me a error like "Unable to find resources for FlexUnitTestRunner".

One way to work around it, was to create a test project, which referenced the test folder of the main project but used en_US as the locale. Not ideal, but it worked without much hassle.

However, i wasn't satisfied with creating test projects for all my Flex projects. After digging a bit into the FlashBuilder plugin directory i found out, that there are two directories for the resources of FlexUnit. One contains the resources for en_US and the other directory contains the resources for the rest of us ;)

My first try was to simply copy the files from en_US to a new directory da_DK. However, the error didn't go away. By looking into the swc library files i found out, that internally they still had a package path en_US instead of the da_DK that i needed.

Next try was to see, if copylocale.exe supports source and target directories, which it doesn't unfortunately. Hm, at least this gave me the idea, that i need something like copylocale, but with configurable paths.

So the third try was to recreate copylocale.exe using ant. The ant script copies the en_US resources to the new da_DK folder. It unpacks the swc library files to a temporary folder. This gives me the original source files for the en_US locale. Next it renames the en_US package to da_DK. And last but not least it compiles the new swc from these source. That works like a charm now. I'm able to use the integrated FlexUnit with a danish locale finally :)

Like copylocale, the actual strings are still in english of course. If you want danish strings, you can do so by manually translating the content of and recompile the swc with the translated file.

Here you can find the ant script.

Happy testing,

Tuesday, May 11, 2010

Fluent Sort builder example in ActionScript

After reading Growing Software i created a factory to create sort objects in ActionScript. It allows you to create sorts like this

var s : Sort = new SortBuilder().byField("status").asString().ascending().byField("date").asDate() .descending().build();

I think, it makes the creation of sorts much more readable. However, now i have to refactor the whole codebase and to educate my coworkers to use it. That's the worst part of it ;)

PS. Xavi published a nice introduction to fluent factories.

Thursday, April 1, 2010

Memory leaks? Yes indeed!

Phase I: Memory leak? No way!
I wasn't convinced when the testers said our Flex app has leaks. I thought it has to do with their machine's configuration or browser or whatever. Even when people came and said, they can see the app leaking in the Flex profiler i wasn't convinced, because i thought the profiler would be lying. In the past i rarely saw our apps leaking so i really thought it is false alarm. Also the randomness of the garbage collector helped to keep me in this mood of false safety.

Phase II: Memory leak? Indeed!
Since the potential bug had a huge impact on the success of the project and we were in the stabilization phase of the project, i had to find out, if it was real.
So what i did to convince myself, was to isolate a small part of the app and create a test app from it. And boom, the leak was clear to see in the instance counts of the profiler.

Phase III: Memory leak? The hunt is on.
First you need to find a set of steps, which clearly demonstrates the leak in the profiler. Ideally you automate this, because during your hunt you will execute these steps again and again.

Then you need to find the leak. Finding out about a memory leak in code, which otherwise looks perfectly good, needs a special mindset. You need to be suspicious about everything really. For me the best way to find it, is to reduce the search space by commenting as much as possible code out, until the leak doesn't show any longer. Then you go backwards by commenting pieces back in, until you see the leak. You can use a approach similar to binary search. You start with commenting in bigger parts until the leak shows, then you split this part and comment out smaller parts until it is gone and so on. Eventually you will find the leak hiding under a place you would never expect it ;)

Phase IV: Memory leaks? The candidates.
So now you have a suspicious line of code. To make 100% sure it is causing a leak, you create a small test project now, which demonstrates the leak in isolation.

Phase V: Memory leaks? The fix.
Now that you know what is causing the leak, you can go through your codebase and fix all the places which contains the suspicious code. If you are lucky, the leak is fixed now. Most of the time there will be no change at all though, because there are other leaks left. So you need to iterate this process and start again with Phase III.

It is a daunting process. I found it useful to pair with a colleague, so when you find something, your colleague can try to reproduce and confirm your theory. Eventually all the leaks are fixed and your app is ready to shine! Puh.

So much for the general process. More specifically we found leaks in our usage of BindingUtils. You need to make sure, that unwatch is called. Also some listeners needed to be removed or to be changed to weak listeners. We found that the SetEventHandler tag in a mxml state was leaking. And last but not least the Degrafa library was leaking, which is used for skins.

Halali (the german death-haloo),

Wednesday, March 17, 2010

Testing all permutations of calls to setters via functional programming

Today i had this class, which has multiple setters and updates bindable properties from the values of these setters. When i wrote a unit test for it, i realized, that i don't know in which order the setters are called. So in principle i had to test all the different orders in which the setters can be called. Al different orders of a list, that's permutations. The class had three setters, which makes for 3! = 6 permutations.

I didn't want to do it manually, so tried to find a way to let the computer do it for me. What i did is to create a function for every call to a setter and a function for the assert. These functions are passed into the assert function like so:

public function whenSearchFormIsUsedInStoreContext_thenCountryChooserShouldBeSetToCountryOfTheStore():void
storeShortcut.countryCode = country2.code;

var setter1:Function = function():void
pm.countriesList = new ArrayCollection([ country0, country1, country2 ]);
var setter2:Function = function():void
pm.currentContext = RecordsModel.IDENTIFY_CONTEXT_STORE;
var setter3:Function = function():void
pm.currentStore = storeShortcut;
var assert:Function = function(permutation:Array):void
assertThat("country2 should be selected, permutation <" + permutation + ">",

assertThatAllPermutationsOfSettersHaveTheSameResult(setUp, [ setter1, setter2, setter3 ],

Now the method can calculate all permutations of the setters array and call the setters accordingly. Works like a charm.

But beware. Faculty is a fast growing function. 7! is 5040 and 8! is 40320. So this method works for a small number of setters only.