Matt

 

My team and I have made some startling observations about ourselves. Firstly, we are all approximately 5’11”, secondly most of us are musicians or hobbyists of some kind. Both similarities are completely coincidental, though maybe there is something more to the latter one.

One of my colleagues often says that when he’s recruiting, he looks for candidates with art or music backgrounds. His justification is that he feels they are smart and have a certain quality that makes it easy for them to pick things up quickly.

Somehow my department is filled with musicians. It’s not part of our screening process, however we’ve come to realize we have music in common. I think this has to do with the fact that when I recruit I look for the qualities that my fore mentioned colleague sees in most artists and musicians.

I play guitar and I know first hand how hard it is to be a good guitarist. There are certainly some people with natural talent, but I’m unfortunately not one of them. Being good takes practice, and lots of it. That’s a defining difference between musician-type and engineer-type programmers. An engineer-type tends to think that being good is a function of how intelligent she is. A musician-type realizes the critical role that practice plays in her path to perfection. Musicians also tend to understand how in the pursuit of perfection, improvements come in smaller and smaller increments however they are no less significant.

Musicians have some of the same internal struggles that engineers do. Take simplicity for example, when I first started soloing on guitar, I had a tendency to throw every note I could into a single line. I eventually learned how important the space in between the notes is, and how simple phrasing can be so much more interesting than a bunch of notes. As a young engineer I struggled with issues of simplicity and complexity for longer than I did as a musician. This could be related to mindset or maturity, either way I acquired an appreciation for simplicity in music much quicker than I did in programming.

At the 2010 Software Craftsmanship North America (SCNA) conference, my colleagues and I noticed a large number of musicians in attendance. It was somewhat of a theme, though not planned. The talk by Keavy McMinn was about her transition from artist to programmer, and Andy Maleh held a lightening talk on the similarities between playing drums and programming. And of course Chad Fowler mentioned his previous life as a saxophonist during his talk.

I really like the idea that musicians make good programmers. I had been thinking since I first started learning agile years ago, that I had previously been building applications that were far to rigid. That’s because I was building programs like you would build a bridge and I really needed to build them like you would a clay sculpture or the melody of a song.

So why do Musicians become programmers? I’ve seen and heard some reasoning around the mathematical nature of both music and programming as a potential cause. However, the theme from SCNA and my own experience seem to indicate that most of us are people who like to make things. Some of us start out with software, others start in music, art, construction or carpentry. All of these are just mediums to fulfill our desire to make new and interesting things. What makes software so appealing, at least for me is the extremely low barrier to entry. You just need to learn a language and have a computer with internet access and you can immediately get started making a computer do things it didn’t know how to do before. It doesn’t cost a lot of money and it doesn’t take a lot of space, it’s mainly a time investment. Software is a very forgiving and flexible medium that allows the people who love to make things to do what they love with the least amount of friction.

 

Lately I’ve been having a lot of fun playing around with the mingle api via active resource. I’ve developed a couple of small projects including one for reporting feature prioritization, as well a release notes generator. As it turns out, the release notes generator is a pretty big hit with our software support staff and the new feature requests are rolling in. Most recently a new feature required accessing the comment history of a story.

The Mingle api is powerful and simple and it makes little projects like these easy and fun. If you haven’t used the mingle api with active resource before, please take a look at my previous post (mingle automation with active resource) or this simple tutorial which I used to get started (tutorial on using mingle with active resource).

As part of our release notes we call out certain stories as having a high support implications, particularly if they modify some legacy database objects or legacy code. Our support department has found this to be instrumental in helping them quickly come up to speed on a new release. In addition to knowing which stories are high profile, it’s also important to know a little detail about these stories. Enter mingle card comments. As part of the release notes we want to include the last comment for each card under the assumption that developers will provide relavant comments before closing the card.

The mingle api documentation says that the comment attribute is only available in the historical versions of a card. Because of this, simply finding a card and grabbing the comment attribute will fail with an undefined method error.

require 'rubygems'
require 'activeresource'

class Card < ActiveResource::Base
  Project = "my_project"
  MyMingleServer = "mingle.weromans.com"
  self.site = "http://#{MyMingleServer}/projects/#{Project}"
end

Card.user = "mroman"
Card.password = "*******"
card = Card.find 555
# this will fail with undefined method
card.comment

The above code fails because I didn’t get a historical version of the card. To do that I need to specify the specific card version we want to retrieve. Since I want to get the last comment posted, I’m most likely going to loop backward through the version history until I find my comment. To do this I’ll need to start with my cards most recent version. I can just open the mingle UI to do that but since I’m already writing code, I’ll do it in an irb prompt, but first i’ll fix my Card class to get rid of that error.

require 'rubygems'
require 'activeresource'

class Card < ActiveResource::Base
  Project = "my_project"
  MyMingleServer = "mingle.weromans.com"
  self.site = "http://#{MyMingleServer}/projects/#{Project}"
end

Card.user = "mroman"
Card.password = "*******"

Now I’ll start up irb in the same directory as my card.rb file.


> require 'rubygems'
=> true
> require 'activeresource'
=> true
> require 'card'
=> ["Card"]
> (Card.find 555).version
=> 6

Great, the most recent version of my card is 6. Now all I should have to do is get version 6 of my card and access the comment attribute. Well, not really. For some reason getting the most recent version of a card doesn’t seem to qualify that card as a historical version which means that your card will not have the comment attribute and your code will still fail.

require 'rubygems'
require 'activeresource'

class Card < ActiveResource::Base
  Project = "my_project"
  MyMingleServer = "mingle.weromans.com"
  self.site = "http://#{MyMingleServer}/projects/#{Project}"
end

Card.user = "mroman"
Card.password = "*******"
card = Card.find(555, :params => {:version => 6})
# this will fail with undefined method
card.comment

If I change my code to get the previous version it appears to work.

require 'rubygems'
require 'activeresource'

class Card < ActiveResource::Base
  Project = "my_project"
  MyMingleServer = "mingle.weromans.com"
  self.site = "http://#{MyMingleServer}/projects/#{Project}"
end

Card.user = "mroman"
Card.password = "*******"
card = Card.find 555
historical_card = Card.find(card.number,
                            :params => {:version => card.version - 1})
card.comment

Success, kind of. The above code returned nil, but I’m taking that as a good sign. This means that my historical_card has a comment attribute, it most likely doesn’t have an actual comment though. If that’s the case all that’s left to do is clean up my code and create a loop to move backward through the card history until I find my comment.

require 'rubygems'
require 'activeresource'

class Card < ActiveResource::Base
  Project = "my_project"
  MyMingleServer = "mingle.weromans.com"
  self.site = "http://#{MyMingleServer}/projects/#{Project}"

  def Card.find_comment_for(number, version)
    card = Card.find(number, :params => {:version => version})
    card.comment
  end

  def Card.last_comment_for(card)
    version = card.version -1
    while ((comment = Card.find_comment_for(card.number, version)).nil?
            and version > 0)
      version -= 1
    end
    comment || "no comment"
  end
end

Card.user = "mroman"
Card.password = "*******"
Card.last_comment_for(Card.find(555))

This solves the requirement, however there is still the open question of what happens if the last comment was created on the last version of the card. Unfortunately as it stands I have not found a way to retrieve a comment on a cards current version.

 

Now for the ruby part. To review; in part one of the Ruby in Java with Maven series, we built a simple maven project which executes java 6 code and fires off a simple JavaScript using the built in JavaScript script engine. Now let’s try another language. If you recall from part 1, the only supported engine was the “Mozilla Rhino” engine which is the built in JavaScript engine. In order to run ruby, we’re going to have to add support for JRuby.

To do this, we’re going to need an implementation of the JRuby scripting engine. Fortunately the kind folks at the java scripting project have already implemented a bunch of scripting engines including JRuby. We just need to download the project, extract the necessary jar and import it into our maven repository to be included in our project. Here’s how…

  • Download the jsr223-engines project from the project downloads page
  • Extract the file to a local directory
  • cd to jsr223-engines/jruby/build
  • Execute the following command to import the lib to your maven repository

$ mvn install:install-file -Dfile=jruby-engine.jar -DgroupId=org.jruby -DartifactId=jruby-engine -Dversion=1.1 -Dpackaging=jar

Once the Jruby engine implementation is installed into your maven repository, you can include both the script engine and the Jruby implementation in your project. Edit your pom.xml to include the following 2 dependencies:

      ...

            org.jruby
            jruby
            1.1
            compile

            org.jruby
            jruby-engine
            1.1
            compile

Wow that was easy. We must have passed the inflection point where maven starts to become useful. If you want to verify that the ruby engine is now supported, you can rerun the code we wrote in part 1 that lists the supported engines.

Now lets write our awesome Ruby script. Create the directory src/main/ruby and store your script there.

# hello_world.rb
# this is a very complex ruby script
puts "Hello world"

Now modify your java to call the ruby script:

package com.weromans;

import java.io.FileReader;
import java.io.FileNotFoundException;
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;

public class App
{
    public static void main( String[] args ) throws
                                             FileNotFoundException,
                                             ScriptException
    {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine rubyEngine = manager.getEngineByName("jruby");
        rubyEngine.eval(
                         new FileReader("src/main/ruby/hello_world.rb"));
    }
}

Now run it:
$ mvn exec:java
[INFO] Scanning for projects…
[INFO] ————————————————————————
[INFO] Building scripting
[INFO] task-segment: [exec:java]
[INFO] ————————————————————————
[INFO] Preparing exec:java
[INFO] No goals needed for project – skipping
Downloading: http://repo1.maven.org/maven2/org/jruby/jruby-engine/1.1/jruby-engine-1.1.pom
[INFO] Unable to find resource ‘org.jruby:jruby-engine:pom:1.1′ in repository central (http://repo1.maven.org/maven2)
[INFO] [exec:java]
Hello World
[INFO] ————————————————————————
[INFO] BUILD SUCCESSFUL
[INFO] ————————————————————————
[INFO] Total time: 2 seconds
[INFO] Finished at: Fri Apr 17 17:25:40 EDT 2009
[INFO] Final Memory: 5M/10M
[INFO] ————————————————————————

As you can see, the Hello world in the above output is from the ruby script. Congratulations, you’re running ruby in the JVM. Let’s take it a step further and pass some data to the ruby script from the Java. First we’ll modify our ruby script to print a variable.

# hello_world.rb
# this is a very complex ruby script
puts "Hello world, my name is #{$myname}"

We are now printing a global variable $myname in our ruby script. Let’s modify the java to pass that variable along to the ruby script.

package com.weromans;

import java.io.FileReader;
import java.io.FileNotFoundException;
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import javax.script.ScriptContext;

public class App
{
    public static void main( String[] args ) throws
                                             FileNotFoundException,
                                             ScriptException
    {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine rubyEngine = manager.getEngineByName("jruby");

        ScriptContext context = rubyEngine.getContext();
        context.setAttribute("myname", "Matt", ScriptContext.ENGINE_SCOPE);

        rubyEngine.eval(new FileReader("src/main/ruby/hello_world.rb"));
    }
}

Run it again:
$ mvn compile exec:java
[INFO] Scanning for projects…
[INFO] ————————————————————————
[INFO] Building scripting
[INFO] task-segment: [compile, exec:java]
[INFO] ————————————————————————
[INFO] [resources:resources]
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory c:Documents and SettingsmromanMy Documentsworkspacejavascriptingscriptingsrcmainresources
Downloading: http://repo1.maven.org/maven2/org/jruby/jruby-engine/1.1/jruby-engine-1.1.pom
[INFO] Unable to find resource ‘org.jruby:jruby-engine:pom:1.1′ in repository central (http://repo1.maven.org/maven2)
[INFO] [compiler:compile]
[INFO] Compiling 1 source file to c:Documents and SettingsmromanMy Documentsworkspacejavascriptingscriptingtargetclasses
[INFO] Preparing exec:java
[INFO] No goals needed for project – skipping
[INFO] [exec:java]
Hello World my name is Matt
[INFO] ————————————————————————
[INFO] BUILD SUCCESSFUL
[INFO] ————————————————————————
[INFO] Total time: 3 seconds
[INFO] Finished at: Fri Apr 17 17:36:02 EDT 2009
[INFO] Final Memory: 12M/22M
[INFO] ————————————————————————

Nice. You can see your line Hello World my name is Matt in the above output. That was pretty easy.

 

Java is a great language. It has many positive attributes, however one thing java is not good for is fast development. Now that I’m older and a little more impatient, I prefer to work in dynamic languages largely because of their short feedback cycle and instant gratification. Over the last few years, there’s been a movement towards the ability to run other languages within the JVM. This makes a lot of sense with the JVM being arguably the best part of Java. It makes it possible to use a dynamic language but still get some of the robustness and scalability of Java. Languages like Jython, Jruby and Jaskel are Java implementations of dynamic and/or functional programming languages that run in the context of a JVM and share a really nifty naming convention.

These languages have been in development for a while but until recently my team has only dabbled with some of them mainly for testing purposes. I haven’t really considered them a viable option for the “if I could only write this in Ruby” problem until recently. Java 6 has made integration of these languages very clean and easy.

The simple scripting inside java is easily demonstrable using javascript since the javascript engine is built into Java 6.

/* hello_world.js */
println("Hello World, I'm javascript")

I am going to attempt to run this super complex javascript from inside the JVM. The first thing I’m going to do is create a new Java project using Maven.

mvn archetype:create -DgroupId=com.weromans -DartifactId=scripting

Since the standard maven archetype doesn’t include a place to keep my scripts, I’ll create the directory ./scripting/src/main/javascript, and copy my hello_world.js file into it.

Just because I’m curious, I would like to see what scripting engines my environment currently supports. As I’ve already stated, javascript is supported out of the box, but let’s go ahead and verify that I’m not just lying to you for fun.

Open up the scripting/scr/main/java/com/weromans/App.java file in your favorite editor or IDE (vi if you’re hardcore), and modify it to include the following:

package com.weromans;

import java.util.List;
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngineFactory;

public class App
{
    public static void main( String[] args )
    {
        ScriptEngineManager manager = new ScriptEngineManager();
        List<ScriptEngineFactory> factoryList = manager.getEngineFactories();

        for (ScriptEngineFactory factory : factoryList) {
            System.out.printf("Engine Name: %s, Language: %sn",
                              factory.getEngineName(),
                              factory.getLanguageName());
        }
    }
}

Let’s just give Maven a little more information about our project so we can compile and run it easily from the command line. Edit your pom file to include the maven-compiler-plugin and the exec-maven-plugin.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.weromans</groupId>
    <artifactId>scripting</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>scripting</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>com.weromans.App</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Now just complie and run it:


$ mvn compile exec:java

You should see the following output:
[INFO] Scanning for projects…
[INFO] ————————————————————————
[INFO] Building scripting
[INFO] task-segment: [exec:java]
[INFO] ————————————————————————
[INFO] Preparing exec:java
[INFO] No goals needed for project – skipping
[INFO] [exec:java]
Engine Name: Mozilla Rhino, Language: ECMAScript
[INFO] ————————————————————————
[INFO] BUILD SUCCESSFUL
[INFO] ————————————————————————
[INFO] Total time: < 1 second
[INFO] Finished at: Fri Apr 17 14:14:45 EDT 2009
[INFO] Final Memory: 3M/6M
[INFO] ------------------------------------------------------------------------

the line Engine Name: Mozilla Rhino, Language: ECMAScript is your applications output and it show’s that the only engine name that is currently supported is Mozilla Rhino which is the javascript engine. Now let’s modify this thing to run our super complex hellow world javascript.

Open up the scripting/scr/main/java/com/weromans/App.java file in the hard core editor of your choice and modify it as follows:

package com.weromans;

import java.io.FileReader;
import java.io.FileNotFoundException;
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;

public class App
{
    public static void main( String[] args ) throws
                                             FileNotFoundException,
                                             ScriptException
    {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine javascriptEngine = manager.getEngineByName("javascript");
        javascriptEngine.eval(
                         new FileReader("src/main/javascript/hello_world.js"));
    }
}

Execute it again:

$ mvn compile exec:java
[INFO] Scanning for projects…
[INFO] ————————————————————————
[INFO] Building scripting
[INFO] task-segment: [exec:java]
[INFO] ————————————————————————
[INFO] Preparing exec:java
[INFO] No goals needed for project – skipping
[INFO] [exec:java]
This is hello from hello_world.js
[INFO] ————————————————————————
[INFO] BUILD SUCCESSFUL
[INFO] ————————————————————————
[INFO] Total time: < 1 second
[INFO] Finished at: Fri Apr 17 15:27:26 EDT 2009
[INFO] Final Memory: 3M/6M
[INFO] ------------------------------------------------------------------------

You can see the hello world output from your javascript. Congratulations, you've just done some scripting in the JVM. I know the title says Ruby in Java, but it also says part 1, so you'll just have to check out Ruby in Java with Maven – Part 2 for the ruby part.

 

The project

I have some very simple release data that I would like to report on a weekly basis. The data includes the target release date, and the feature sets and feature set benefits that are targeted for delivery in the current release. Fortunately all of this information is stored in our project management and collaboration system as a result of our release and iteration planning procedure.

Mingle is a project management/collaboration system for agile projects. Since we do all of our planning in mingle, and since the development team uses the it to keep track of their work, it’s always up to date and it’s got all the information I need for this task.

I’m a little bit on the lazy side when it comes to procedure and I’m a firm believer that process and procedure is something that should exist in the background and help us do our jobs. Once you’re spending a lot of time managing your procedures, they cease to be helpful. Enter automation; I don’t want to be bothered with manually extracting information from mingle every week and emailing it. As it turns out, mingle is written in rails and it has a restful API. This makes it very easy to access mingle data via http. My task is made even easier by the fact that rails offers ActiveResource which maps RESTful resouces similarl to the way ActiveRecord maps database objects.

The Setup

We’re using mingle for our planning and team collaboration. We have cards in mingle for Bugs, Spikes, Stories, Iterations, Releases, Feature sets and Segments. We also have card trees for managing relationships between these card types.

Our release planning tree is used for bucketing stories into releases and later into iterations. This tree is constructed as:

    Release > Iteration > Story

Our feature planning tree is used for story writing and starts with very general segments (also referred to as theme’s), then breaks down into feature sets (or epics) and finally to stories, like so:

    Segment > Feature Set > Story

From the above trees it’s possible for stories from a single feature set to be developed in 2 separate iteration or even releases.

The Implementation

I was only able to find very limited documentation on the mingle api, and even less on using active resource with the mingle api. However i did come across this tutorial on using mingle with active resource which was a very close match for what i was trying to do.

The first thing I had to do was create the Card class which implements ActiveResource::Base and configures the site url.

require 'activeresource'
class Card > ActiveResource::Base
  self.site = "http://#{User}:#{Password}@#{host}/projects/#{Project}/"

  ...
end

Our release cards contain a start date and a projected end date, other than that they serve as a top level parent in the release planning tree. I also needed to pull the release date out of our release card. This part was pretty simple:

def Card.find_release(release_name)
  card = Card.find :first,
      :params => { :filters => ["[name][is][#{release_name}]"]}
  card.cp_end_date
end

Following that I need to pull all the feature sets for the current release and extract some description data. Since I know all the stories in a release, the ideal way to retrieve the feature set cards would’ve been to get the stories for the release and then back into the feature sets using the feature set card tree. This turns out to be more difficult than it sounds. Mingle uses 2 fields for identifying cards. There is the id, which is the underlying database index, and there is the number, which is the application level card number. Unfortunately some operations use id and some use number. Specifically, GET uses number and POST uses id. Card tree relationships are defined using id as the foreign key. What this means is that while it’s possible to get a card using its number, then post changes to it using it’s id, it’s not possible to look up a card based on a card tree relationship using foreign key which is an id.

The following will not work based on this id/number issue:

stories = Card.find :all, :params => { :view => "Current Release"}

feature_ids = stories.collect {|story| story.cp_feature_tree___feature_card_id}
feature_ids.uniq!

features = feature_ids.collect do |id|
  Card.find :params => { :filters => ["[id][is][#{id}]"]}
end

Fortunately I had another option. During our release planning process, before we pull stories into a release, we tag the feature set with a release tag (using mingle tags). We use this tag as a bookmark so that we can remember which feature sets should be delivered in the release while we are in the process of story writing and estimating. The mingle API for tags is pretty solid and easy to use.

features = Card.find :all,
    :params => { :tagged_with => release,
                 :filters     => ["[Type][is][Feature Set]"]}

features.each do |feature|
  email_body << "#{feature.name}nBenefit: #{feature.cp_benefit}nn"
end

Although the code ends up simpler, this solution isn’t ideal since previously tags were only an artifact of our planning process and also because the code is less expandable. I am certain that I will eventually want to report additional story level information and I don’t have a way to map feature sets to stories.

This was a very simple automation project. The mingle API is far more sophisticated than this project illustrates. The mingle API shows a lot of promise for integration into our build process.

 

Sometime last year I came across Dave Thomas’s Code Kata page and I thought, what a great way to learn a new language, or even just shake the rust off. Eventually I learned that some teams practice code kata’s together. This is known as a code dojo. Since I enjoy team building possibly more than I like software building, dojo’s make kata that much more intriguing.

Why dojo’s? Let’s face it, there are some serious limitations to learning on the job. Sure, Apex Tech seems to like the idea, but even they have a standard curriculum you must follow before you graduate with the tools of the trade. The problem with learning software on the job is the occasionality of the problems which catalyze the lessons. Some very important lessons may go unlearned based on how frequently they come up, or based on the level of exposure to the problem your role permits. There are certainly some common skills we must all acquire and some common lessons we can all learn which will help us avoid repeated mistakes in the field of software development.

We software developers have an additional problem, our craft is quite young. It’s only recently that we’ve started to shift away from thinking of it as a field of Engineering, and college programs haven’t even perfected teaching the engineering version of it yet. It will be decades before programming students begin to enter the field with the required skills to hit the ground running. Collectively, we are far too reliant on “on the job training.” Code dojo’s are a great way to start learning those common lessons in a training environment, as well as help unearth some of the team incongruities that go unadressed in our our day to day work and often slip under the radar of our retrospectives.

I have come across 2 types of code dojo’s. A simple kata is a staged execution of a solvable problem. Kata’s allow the group to watch solution performed illustrating good form. A randori dojo is more dynamic and interactive. In a randori the team collectively codes the problems solution.

Wikipedia currently defines a randori as: a term used in Japanese martial arts to describe free-style practice or sparring, sometimes with multiple attackers. The term literally means “chaos taking” or “grasping freedom,” implying a freedom from the structured practice of kata. This definition may be what intrigued me the most. The most effective form of practice resembles reality closely. In a randori the the problem is fairly simple, it should be something that the team can easily get their heads around. The focus shouldn’t be on the problem, but rather the techniques used to solve it, and the problems that arise during the course of the randori. It is not necessary to solve the problem completely. Similarly to rock climbing, it’s about the climb, not the summit.

For our randori’s we have adopted the rules that are very well laid out by Agile Finland on their code dojo page. The rules of the randori like anything else on an agile team are subject to reflection and modification. Each randori ends with a quick retrospective, the output of which helps refine our rules.

  • There is a coding challenge that is announced beforehand.
  • There is a room with one computer attached to video screen and set up as a pairing station (2 keyboards, 2 mice).
  • The presenter explains the coding challenge and starts the Randori with a pair from audience.
  • One half of the pair is changed every 5 minutes.
  • The pair on the keyboard should continuously explain what they are doing.
  • The pair on the keyboard should stop when someone from the audience falls off the sled — and only continue when that someone is back on track again.
  • The audience should give comments on design only when there is green bar. (During red bar audience can only ask questions)
  • The pair should not continue on writing new code if other participants are not happy with the current design (The code should be always well refactored before starting to write new code)
  • The pair will use TDD (Test-Driven Development), preferably employing the ping pong model of writing and passing tests.
  • The programming language to be used is announced in advance per session.
  • The maximum number of participants is limited to 15.
  • The presenter acts as a product owner
  • The actual coding is done in small iterations. There are short planning period before every coding iteration.

Some randori’s end up being clean practice session and a knowledge exchange for best practices and good craftsmanship. They usually start off a little rough but really gain momentum during the second iteration. These randori’s have helped us model good behavior in terms of TDD and pairing. Other times we’ve run into a rut which prevents us from making good progress on the randori problem. We find these randori’s to be even more valuable than the former. They expose the problems that hinder us during our day to day work but are less noticeable in the broader context of an iteration.

 

Yes it’s true. Managers love metrics. Some managers may even attend clandestine weekend meetings to come up with more useless numbers to apply to the work that developers do. As we know from the days of LOC (Lines Of Code), these fail to capture the value or productivity of developers and sometimes mismotivate developers.

There is a lighter side of metrics though. They do have a critical place in software development, however it’s not for managers to measure their developers rather for developers to understand their code.

Even LOC has value, in fact it’s one of my favorite metrics. It’s now usually referred to NCSS (Non Commented Source Statements). This metric was once used to measure productivity as if more lines of code was a good thing. Ugh! Now we use NCSS to point out when we have too many lines of code. Imagine that, the managers had it backwards. NCSS is such a simple metric and yet it’s very powerful. It’s usually applied at the method level and is a clear indicator that you have large, complex and difficult to understand methods. Although there is no set number of lines per method that you should conform to, the general guideline is based on amount of time it takes to clearly understand a method. It should not take more than a couple of minutes to fully understand a method, and in my experience those methods rarely have more than 10 or so lines. Small methods that do one thing only and are appropriately named are easy to understand, so let NCSS help you find those methods that aren’t.

Another indicator of complexity is McCabe Cyclomatic Complexity (aka CCI or CCN). If you’re a masochistic feel free to check out the wikipedia definition, or you can just trust me and accept that it’s a good relative indicator of methods that have complex execution paths. For example, a method that has many return statements, nested conditionals and loops, and maybe even a few try/catch/throw statements for good measure. The greater the number of paths through your method, the higher your cyclomatic complexity. Since good unit testing would require you to cover all paths and CCI measures the number of paths in your method, CCI can also be an indicator of the number of tests you would likely need to get good coverage. Often you will see overlap between NCSS and CCI, just by the associative nature of size and complexity.

When using metrics to understand your code or to find deficiencies, be cautious to remember that these numbers are only indicators. It’s easy to see a nice number and think everything is OK. Not so. For example, another favorite metric of mine is code coverage. Code coverage tells you how many and which lines of code your unit tests are hitting and it’s usually expressed in percent of lines of code and percent of branches covered. I recall joining a project and running cobertura (a code coverage tool for java) to find out the project’s level of coverage. I was delightfully surprised by a relatively high number and so I went about my business of refactoring and changing code. When I eventually broke the code, I was surprised that it hadn’t been detected by the extensive test suite. After some inspection I realized that just because your test hits a line of code doesn’t mean that line is actually being tested. What I found were lots of tests with lots of System.out’s and very few assertions. The lesson here is to let your metrics point out problems, but if they tell you all is well check up on them. There is a saying in Journalism, “If your mother says she loves you, check it out.” This same skepticism should be applied when using code metrics.

 

As a programmer I never had the pleasure of working on a team that had effective code reviews. In fact, I don’t ever recall being in a code review. I certainly remember a lot of lip service being paid to the importance of code reviews, just never actually saw one. Maybe that was because of bad management, or maybe code reviews weren’t as important as we thought, or maybe we tried and failed, or maybe we were having code reviews every day but they were so horribly unrecognizable that I just thought they were something else.

Later in my career, I still believed code reviews were important, but mostly dismissed them because I never knew how to make one work successfully. In fact, I wasn’t sure what success for a code review was. I thought of code reviews as one developer presenting her work to the rest of the team, and the team in turn making comments and suggestions of which most would be difficult or impossible to implement or maybe even make management throw up a little in their mouths. I also pictured the scope of the work being reviewed to be way beyond the scope of the meeting making it impossible to get any real analysis done in 1 to 2 hours.

Well I’m happy to announce that I was wrong and code reviews can in fact be very successful and for us, success is defined by the following criteria:

  • Everyone learns something
  • No one feels attacked
  • We reduce knowledge concentration risk
  • We discuss craftsmanship
  • A non superficial understanding of the code under review is achieved by all
    Suggestions are easily implemented within an iteration (for us that’s 2 weeks)
    We get all this done in 1 hour

We achieve this by:

  • Making the review about a metric and not a component
  • Selecting a unit of code as small as a single method
  • Discussing the smells associated with the code, particularly ones which affect the selected metric
  • Discussing the refactorings necessary to improve the code which in turn improves the metric
    Creating dev tasks for those refactorings to be implemented in a future iteration

An example focused code review goes like this. The team selects a metric they would like to use as the lead in. It is important to remember that the metric is the starting point, not the focus. We want to remember that we’re meeting to improve our code, our standards and our practices, not our numbers. The selected metric then selects the unit of code for us. Sometimes this is a method, sometimes a class depending however it’s rarely bigger. We write up a list of code smells that we can detect in the code unit and pay careful consideration to those which affect the metric. We then select the appropriate refactorings to improve the code. Usually we detect smells right from the Martin Fowler text, Refactoring, other times we coin our own smells which are then documented in our wiki. Dev tasks are created for the refactorings and prioritized against our backlog. When the refactorings are actually implemented they may be done by anyone in the group. Sometimes the original author does the work, sometimes she may be part of a pair and other times she may not be involved at all. The main concern is that we expose the problem in the code, and in the practices that created that code. Although it will eventually be fixed in the code, it’s more important that it’s fixed in our practices first.

Some fun metrics to start with are:

  • NCSS (Non Comment Lines of Code): the measure of lines of executable code in a method. The bigger the method, the higher the likelihood that it will be difficult to understand, and that it’s likely doing too much.
  • CCN (or CCI, Cyclomatic Complexity Index): An indicator of the number of paths through a method. A Higher number represents a higher complexity. Which means the method should be refactored into smaller methods.
  • Churn (or Developer Activity): the number of times the file is checked in. A relatively high number implies that the class is responsible for too much.

It is a good idea to change the metric you’re using as different metrics will inspire different conversations.

© 2012 WeRomans Suffusion theme by Sayontan Sinha