bookmark_borderFacilitating the Global Day of Coderetreat 2013 in Amsterdam

On the 14th of December 2013 – the Global Day of Coderetreat was held at ZilverlineI have experience with coderetreats and also organised one at the 7th of january in 2012, and the GDCR12.

This time I both hosted and facilitated this event. This means that besides practical stuff I also did the talking which I will explain further in this post. This was the first time I did this and I’d like to share how it was. If you want to get an impression of the day you can have a look at this slideshow.

A big thanks to Bob Forma and Diana Sabanovic who helped me with the hosting aspects throughout. This enabled me to mostly focus on facilitating.

I was anxious, especially since last years GDCR was very well done. Back then I had a great experience and I was not sure if I could give the participants the same experience. Yet, I wanted to do this: I just love sharing knowledge and give people something to learn or think about.

After attending the GDCR Facilitator Training by Jim Hurne, I had a clear image of how I wanted the participants to experience the Coderetreat: People having fun, learning from each other and the constraints given.

Thats it.

Continue reading “Facilitating the Global Day of Coderetreat 2013 in Amsterdam”

bookmark_borderStuff I’ve learned #02

Some time has passed, and I’ve learned new stuff again:

  • Updating a single gem is not done with ‘bundle update <gemname>’ but in fact with ‘bundle update –source <gemname>’. See this post for more info on that.
  • Mailbox (iOS) is a really neat mail program. I really love this ‘remind me later’ stuff which keeps my mailbox clean and keeps me from writing these reminders myself in the Calendar app.
  • With CTRL-F2 you can get focus on the menu bar in any mac app. (more keyboard shortcuts here)
  • With JSONLint you can easily verify JSON.
  • In Ruby you can actually create a Hash using brackets with key, value order. Ie like: Hash[“myKey”, “value”, “myOtherKey”, “myOtherValue”]. The [] is a class method.
  • I am really happy that we spent time creating a ‘load dump from environment X into my dev environment’ so we can easily test migrations and fix lots of bugs beforehand (instead of having to solve issues while deploying to an environment).
  • When using ZShell and you want to issue a rake task you cannot pass parameters with [] (ie rake myjob[someparam] won’t work). You need to use single quotes around the jobname + its parameters. Ie: rake ‘myjob[someparam]’ works.
  • You can download free, legal, VM’s to test IE versions on different versions of Windows (here)
  • You can create your own events with SDL using User events., as is done here
  • The Global Day Coderetreat 2013 will be held at the 14th of December and we (at Zilverline) host one!

Thx to Sander for his tips about MailBox and ZShell.

bookmark_borderAnother reason to participate in a coderetreat

I’ve attended a coderetreat not so long ago in Rotterdam.

I have talked about coderetreats before; how they help improve your skills.

The most important reason to join coderetreats however is to just have fun.

I had a good time!

Why don’t you join a coderetreat event nearby and have a good time as well? 🙂

DSC_4348

bookmark_borderWorking with legacy code – how to start & reveal intent

Recently I posted my opinion about regression. Regression bugs are likely to occur on projects with a lot of legacy code. I consider legacy code as untested code.

At the legacy coderetreat we used a small codebase (you can find it here). With that codebase we exercised in sessions to improve the code. The nice thing is that this is very similar with your daily job. You open up a project and you have to make changes in code you haven’t seen before and do not understand.

In order to get a better understanding you can use various techniques. I have practiced them with the legacy coderetreat and also applied this at work. In this blog post I’d like to share my experiences. Btw: If you haven’t experienced a coderetreat yet, join one. Just like kata’s, they are really worth your time (and more fun)!

Step 1: Get a sense of what is happening
Before we can do anything, we have to understand what we need to change and how it has impact on the system. One way to find out is to simply execute the code. You could just run the application, or… you could try to write a simple unit test executing the ‘main method’ you think that should be ran. Poke around with the parameters, and see what happens.

I prefer writing Characterization tests. The benefit is that while I am trying to understand what is happening, I am also building a safety net. Writing a Characterization test goes like this:
– create new test
– do some setup
– run specific piece of code (method) you want to try out
– check outcome / read state
– create assertion to make it pass with the outcome

When I don’t know what it actually does, I call my tests ‘monkey‘. Once I know the behavior with the given input, I rename the test to what the behavior is. Example:

package com.adaptionsoft.games.uglytrivia;

import org.junit.Assert;
import org.junit.Test;

import static org.hamcrest.core.Is.*;
import static org.junit.Assert.*;

public class GameTest {

	@Test
	public void isPlayableReturnsFalseWhenInitialized() {
		Game game = new Game();
		assertThat(game.isPlayable(), is(false));
	}

	@Test
	public void isPlayableReturnsTrueWithTwoPlayers() {
		Game game = new Game();
		game.add(&quot;Stefan&quot;);
		game.add(&quot;Niels&quot;);
		assertThat(game.isPlayable(), is(true));
	}

	@Test
	public void monkey() {
		Game game = new Game();
		game.add(&quot;Stefan&quot;);
		game.add(&quot;Niels&quot;);
		game.roll(5);
		// no idea yet what happens, need to look into roll method to get a clue
	}

}

So this gives me a rough idea what is happening, and it gives me a suite of tests.

It is important that you focus on black box tests. Try not to bother about the internals. If you are deep-stubbing in your test setup then try to think of a different way to approach the problem. Sometimes it is not possible to do black box testing, only then you need to do white box testing. In these cases deep-stubbing is often needed. Deep stubbing indicates a design problem: your class is bothered with internal states of other objects. You can reduce this by applying Tell Don’t Ask.

Step 2: Reveal intent.
This is even less invasive (actually it is not invasive at all if done well) than the small refactorings I have blogged about in the past.

To reveal intent:
– go through the code, find magic numbers and strings. Introduce constants for them with descriptive names
– find method names that do not describe well their behavior, and rename them. Try to keep the name about behavior, and if it does more then one thing, concate these behaviors with “And”.
– do the same for variables

This may sound trivial, but it really enhances the understandability of the code. As a bonus your understanding of the code is increased a lot, and all you did was renaming things and perhaps introduced a few constants. Let me show you how much it matters:

Can you find things to improve in this code?

if (roll % 2 != 0) {
	isGettingOutOfPenaltyBox = true;

	System.out.println(players.get(currentPlayer) + &quot; is getting out of the penalty box&quot;);
	places[currentPlayer] = places[currentPlayer] + roll;
	if (places[currentPlayer] &gt; 11) places[currentPlayer] = places[currentPlayer] - 12;

	System.out.println(players.get(currentPlayer)
			  + &quot;'s new location is &quot;
			  + places[currentPlayer]);
	System.out.println(&quot;The category is &quot; + currentCategory());
	askQuestion();
} else {

What about this?

if (roll % 2 != 0) {
	isGettingOutOfPenaltyBox = true;

	System.out.println(players.get(currentPlayer) + &quot; is getting out of the penalty box&quot;);
	places[currentPlayer] = places[currentPlayer] + roll;
	if (places[currentPlayer] &gt; PLACE_BEFORE_STARTING_PLACE) places[currentPlayer] = places[currentPlayer] - MAX_PLACES;

	System.out.println(players.get(currentPlayer)
			  + &quot;'s new location is &quot;
			  + places[currentPlayer]);
	System.out.println(&quot;The category is &quot; + getCurrentCategoryForCurrentPlayerOnPlace());
	askQuestionAndRemoveFromQuestionFromDeck();
} else {

This method name is called “roll” initially. If you would sum up all its behavior it would be more like:

	public void movePlayerAmountRolledAndAskQuestionOrWhenInPenaltyBoxIfUnevenRolledGetOutOfPenaltyBox(int roll) {

Who would ever accept such a long method name? I would, but it should trigger something. This method name tells you there is way too much going on in one place. And, since the method is public, we communicate to other classes what this thing is doing.

It is ok to rename multiple times. The longer you work with the code, the better you understand it. When the method names do not reflect their real intent, make it clearer and improve their names. Communicating what the code actually *does* is important, make it explicit. especially if the method name violates conventions (ie, a getSomething() method that is not getting a property, but does more than that.)

It is very tempting to extract expressions and methods
Before you do this. Make sure you have the Characterization tests and integration tests in place. The tests will tell you if you have broken something while refactoring using extract method or extract conditions into variables. Yes, even such small refactoring’s could cause bugs.

Here an example, take this expression:

	if (rolled % 2 != 0) {

Which you could turn into (extract into variable):

	boolean isUnevenRoll = roll % 2 != 0;
	if (isUnevenRoll) {

Or extract method:

	if (isUneven(roll)) {

I prefer (automated!) extract method over extracting into variables. The main reason is that extracting into methods introduce very small pieces of code that you can re-use. You could eventually even find that the methods are not particularly bound to the current class’ behavior and move them out of this class into a new class. With variables this is much harder to see and refactor.

With these two steps, we could have brought the code we had earlier into a state like this:

if (isUneven(roll)) {
	isGettingOutOfPenaltyBox = true;

	System.out.println(getCurrentPlayer() + &quot; is getting out of the penalty box&quot;);
	moveCurrentPlayer(roll);

	System.out.println(getCurrentPlayer()
			  + &quot;'s new location is &quot;
			  + places[currentPlayer]);
	System.out.println(&quot;The category is &quot; + getCurrentCategoryForCurrentPlayerOnPlace());
	askQuestionAndRemoveFromQuestionFromDeck();
} else {

Conclusion
When working with legacy code, it is of importance to understand the code before making changes. In order to understand the code we can use introduce constants or rename methods to make the code reveal its intent. Using Characterization tests we can fixate the current behavior and label it in our tests names. Then, once we have this test suite, we can start using small refactoring’s like extract method or extract variable to make conditionals reveal their intent.

When creating a test suite, creating mostly black box tests will help us in the future when refactoring opposed to white box tests. Sometimes white box tests cannot be avoided.

Without any tests we can already have more insight in what is happening. With a test suite we can more safely start refactoring.

More about coderetreats
I have been greatly inspired by the legacy code retreat day, where we could experiment more in our spare time. Just like the previous time I have learned a lot, and I am convinced that others will benefit from this as well. Therefor I have decided to lend a hand and offer to organize and facilitate a coderetreat myself at the end of this year. Stay tuned!