Posts tagged ‘Code Kata’

I’m having fun with this KataArgs. In my last post, I took a closer look at Bob Martin’s Java and Ruby solutions to it. Since then, we have tackled this Kata at a couple of GothPy meetings. (My coding dojo; the code is here.)

Several of us did some more work on the kata individually after the meetings, and a lively discussion on our mailing list ensued. I also challenged the local Ruby user group Got.rb to have a go at it, and one person posted his solution there too.

It’s all good fun, anyway, and hopefully we’re all learning something about what we mean by “clean code” along the way.

Over Christmas I finished reading the book “Clean Code” by Robert C. Martin. I thoroughly recommend the book, which is highly practical, technical and well written. In it, Bob seeks to present the “Object Mentor school of clean code”, as he puts it, “in hideous detail”.

The book is full of code examples, clean and less clean, and detailed advice about how to transform the latter into the former. All the examples are written in Java, though, which leaves me wondering a little if “clean code” in the Object Mentor meaning of the word, looks the same in other languages.

In Chapter 14 of the book, there is a fully worked example of a little coding problem that I would call a code Kata. It’s a little program for parsing command line arguments. I know, there are loads of libraries that do this already. But never mind. It’s a non trivial problem yet small enough to code up fairly quickly. One thing that caught my attention was the footnote on page 200, just after he has presented his best Java solution to the Kata. “I recently rewrote this module in Ruby. It was 1/7th the size and had a subtly better structure.” So where is the code, Bob? What is this subtly better structure?

I had nothing better to do on Boxing Day than sit around and digest leftover-turkey-curry, so I sent a little mail to Bob asking him for the code. To my delight, I got a mail back only a few hours later, with a message that I was welcome to it, and the url to where he’d put it on github. Evidently Bob also had time on his hands on Boxing Day.

I have had a look at the Ruby code, and although my Ruby is fairly ropey, I think I can follow what it does (surely a sign of clean code?). The design is very similar to the Java version presented in the book, with a couple of finesses. (The next part of the post will make most sense if you first look at Bob’s Java version and Ruby version).

The first finesse I spotted, is that the Ruby version defines the argument “schema” in a much more readable fashion. Rather than “l,p#,d*” as in the Java version, it reads


parser = Args.expect do
boolean "l"
number "p"
string "d"
end

ie the program expects three flags, l,p, and d, indicating a boolean, number and string respectively. You can do this in Ruby but not Java because the language allows you to pass a code block to a method invocation. (the stuff between “do” and “end” is a code block, and the class “Args” has a method “expect”) I think the Ruby version is rather more readable, don’t you?

The second finesse I can see is that the argument marshallers dynamically add themselves to the parser, rather than being statically declared as in the Java version. This means that if you discover a new argument type that you want to support, in the Java version you have to crack open the code for Args.java and add a new case statement in the “parseSchemaElement” method, as well as adding the new argument marshaller class. In the Ruby version, you just add the new class, no need to modify an existing one. Bob invented the Open-Closed principle, so I guess it’s not so surprising to see him following it 🙂

So in Args.java:


private void parseSchemaElement(String element)
throws ArgsException {
char elementId = element.charAt(0);
String elementTail = element.substring(1);

// long if/else statement to construct all the marshallers
// cut for brevity
[...]
else if (elementTail.equals("#"))
marshallers.put(elementId, new IntegerArgumentMarshaller());
else if (elementTail.equals("*"))
[...]

or in the Ruby code, each marshaller just tells the parser to add itself:


class NumberMarshaler
Parser.add_declarator("number", self.name)
[...]

in the Parser class:


def self.add_declarator(name, marshaler)
method_text = "def #{name}(args) declare_arguments(args, #{marshaler}) end"
Parser.module_eval(method_text)
end

def declare_arguments(args, marshaler)
args.split(",").each {|name| @args[name] = marshaler.new}
end

You can do this in Ruby but not Java, since in Ruby you can dynamically construct and execute arbitrary strings as code, and add methods to classes at runtime. (The string declared as “method_text” is constructed with the details of the new marshaler, then executed as Ruby code in the next line, by Parser.module_eval) This is an example of metaprogramming.

So it seems to me that the “subtly better structure” that Bob refers to in his footnote, is made possible by powerful language features of Ruby, such as metaprogramming and closures.

Of course my favourite programming language is Python, which also has these powerful language features. I am rather interested to see if I can come up with an equally clean solution in Python. I am also interested if any hotshot Java or Ruby programmers out there can improve on Bob’s solutions. To this end, I have added a description of this Kata to the catalogue on codingdojo.org. We had a go at it at our last GothPy meeting, without any great success, although I hope we might do better at a future meeting.

So please have a go at KataArgs and see if you can write some really really clean code. Do let me and the community on codingdojo.org know how you get on!

At the XP2007 conference, Geoff and I presented a workshop entitled “The coder’s dojo: Acceptance Test Driven Development in python”. (Geoff also presented the same workshop at agile2007). We had three aims with this workshop, the first was to use the meeting format of a coders dojo, the second was to do some coding in python and the third was to demonstrate how you can do Acceptance TestDriven Development using TextTest. We felt the workshop went well, we had around 30 participants and we were able to do a little of everything we had set out to do.

Perhaps the most important thing was what we learnt from the experience. The workshop participants gave us some very useful feedback. One thing people said was that there were too many new ideas presented to expect as much audience participation as we did, and that instead of trying to do aRandori style kata, we should have done it as a Prepared kata. There also seemed to be a view that the Kata we had chosen (KataTexasHoldEm) was quite a difficult one. Another very valuable piece of feedback was that we were doing Test Driven Development (TDD) with much larger steps than people were used to.

What I have done is to create a screencast in an attempt to address this feedback, and open up our workshop material to a larger audience. In it, I perform a Prepared Kata of KataMinesweeper, doing TDD with TextTest and python. Geoff and I have been developing this approach to testing for a few years now, and we think it deserves consideration by the wider agile testing community. There are important advantages and disadvantages compared to classic TDD with xUnit.

I will write an article about this approach and provide links to the screencast in my next post on this blog.