Tuesday, June 30, 2009

Using Anonymous functions as event listeners

I am working in ActionScript right now, but I think we can do something similar in C# as well.

I am not 100% sure this is a good trick, but it works. If anyone thinks of a reason why we should not do this, let me know.

Problem: ClassA wants to listen to some events of ClassB. That's very simple, we just subscribe to that event. Since we needed some local context, we decided to use anonymous method to listen. Once the event occurs, we would like to un-subscribe from the event. There are two reasons why we might want to unsubscribe.

1. We do not want to perform that task again - which will be very specific to what you are really trying to do.

2. We want all our objects to be garbage collected. Not unsubscribing from events is the surest way to introduce memory leaks.

Solution: Use a variable of type "Function".

1 var listener:Function = null
2 instanceOfB.addEventListener(Event.EventName,
3         listener = function()
4        {
5                //do whatever you need to
6                instanceOfB.removeEventListener(Event.EventName, listener)
7        }        
8 )

See lines 3 and 6.

In C#, if I remember C# correctly, you would need a variable of type "Delegate". And yes, ActionScript does depend on event "name" while managing events. I like the C# mechanism much better.

Friday, June 19, 2009

TDD guidelines - from painful experience of violating them

  1. I cannot stress this enough. Always let the test fail first. Make sure it is failing for exactly the reason you want it to fail. Then write code (just enough) to make it succeed. Oh, I know red-green-refactor is the basic cycle and you might already know it. But in the initial stages, I used to be a bit lazy and skip the red. Come on, I know its going to fail, let me write the code and make it successful. I used to run into problems, and it seemed a longer process than it should have been. When I started following the cycle closely, there were many times when the test itself was incorrect (wouldn't fail even without writing code hahaha!). I realized the importance of "red" step then.
  2. While we are talking about shortcuts - understand that refactor is an important part, and understand that it comes after green for a reason. Remember, its not red-green-red-green-red-green-refactor. It is red-green-refactor. Also, its not red-green with great code everytime-red-green with...
  3. Refactor includes refactoring tests (something I have been guilty of avoiding many times). No refactoring in the cycle should go for more than 15 mins. Oh, I have violated that as well, and as a result, had to abandon tdd for a few weeks ;)
  4. If you ever take a shortcut, and write the correct code (because it is so obvious, it would be stupid not to get it right first time) and that means it implicitly covers some conditions not in your test, write enough tests till it seems impossible that the code would fail. Remember, even the simplest code can have bugs. Yes, the smartest of us do it. No, you are not better than the rest.
  5. Remember that the code may change later. What seems impossible to go wrong right now, may actually happen later. The decision to write a test should be based on considering the code as a black box. Knowing how the code is written should probably only increase the number of tests, not decrease it.

Whenever I visit Fowler’s web site, I find some ditty that makes the experience worthwhile. One of the wonderful points that I found recently was that when adding a new feature, you should probably look at your current test suite and see if there are some tests that you can modify to test the changes. This is not to say cram asserts for multiple unrelated things in the same tests, but a large number of tests will also seem daunting to maintain (duh!)

I intend to have at least one link to a better person/developer/writer’s blog than mine, for every entry that I write. That way, if you are bored here, you at least get diverted somewhere better. Here is the link for today: