Thu, 01 Jun 2006

Tidying Up

A few hours ago I got stressed about the lack of leg room under my desk and ended up spending the next few tidying and moving all of my computers to under the next desk. I also made the mistake of starting to remove keys from my keyboard to clean something sticky and found myself surrounded by keys and a keyless keyboard. It's now nice and shiny, which is more than can be said for the rest of the flat, which is now overrun with all the crap that was around my desk.

Another thing that could do with a tidy up is Eddie, my Java liberal feed parsing library. After the initial coding sprint, I've had time to sit back and look at the design of the library and clean up any thing that sticks out. As mentioned in a previous entry, one of the things that has bothered me is that when ever you need to call an object method, you need to be certain that the object is not null. The means you end up with code like:

if (string != null && strong.equals("string")) {

This quickly becomes tiresome and the test for null distracts from the meaning of the code. Fortunately I was reminded of an improvement for string objects. Ideally, we should all be writing comparison conditionals like rvalue == lvalue. (an rvalue mostly is an expresion you can't assign to). The most common rvalue is a literal value like a string constant. The advantage of getting into the habit of writing code like this is that you'll discover at compile time when you accidentally write = rather than ==. Because you can't assign to an rvalue, the compiler will complain. What makes this interesting from a java string point of view is that you can call methods on string literals. Comparing a variable to a string literal, rather than calling .equals() on a variable is that the string literal is not going to be null, so you can remove the test for null and simplify the code:

if("string".equals(string)) {

I know it's not everyone's cup of tea, but I prefer it to testing for null every time I look at a string. The other thing is that I've been reading Hardcore Java by Robert Simmons at work. Considering I've only got a few pages in so far. I've received a surprisingly large number of ideas to improve my code.

The one that sticks in my head is using assert for doing post and pre conditions on your functions. Using asserts have number of advantages over throwing exceptions, including the fact they get optimised away when you do a production release. In Eddie, during a <feed> element I determine the version of Atom that we are parsing. This had a number of nested if/else if/else blocks. At the end of the function, I wanted to make sure I had set the version string to something, so had the following code:

if (!this.feed.has("format")) {
   throw new SAXParseException("Failed to detect Atom format", this.locator);
}

However, using assertions I can write this as

assert(this.feed.has("format")) : "Failed to detect Atom format";

I highly recommend the Hardcore java book if you want to improve your java programming. It includes sections on the new features of Java 1.5 and using collections. I've made a couple of other cleanups including going through member variable access specifiers to make sure they are right and making several public methods and variables and making them priavte. I also have a couple of ideas about refactoring some of the code to clean it up. Redesigning and refactoring code is almost more fun than writing it in the first place. You get to be in competition with yourself, challenging yourself to write better code and end up with cleaner code in the process.

A couple of things I want to do in the near future is use a profiler and code coverage tools. If anyone has recommendations for either of these tools that integrates nicely with eclipse, I'd love to know.

[] | # Read Comments (5) |

Comments

A couple of gotchas about asserts in Java. First make sure you're compiling with '-source 1.4' or above. Otherwise javac will remove your asserts.

Secondly, make sure you run java will assertions enabled, i.e.:

java -ea ...

By default Java will not enable assertions, which is a terrible decision IHMO.
Posted by Miles Barr at Fri Jun 2 00:03:11 2006
Additionally to what Miles said: Make sure you use assertion only for catching programming errors, not errors in external input. From the example you give it seems that you are testing whether the input you get is really an atom feed. This means that a caller of that method has to test this itself:

  if (is_atom_feed(feed))
  call_your_method(feed);
  else
  error_handling();

But in general I really like to use assertions for testing post- and preconditions. I use this in C, C++, Java, and Python. The GNOME platform libraries (glib to me more precise) even offer an assertion mechanism of their own, which is used liberally.
Posted by Sebastian Rittau at Fri Jun 2 09:32:59 2006
The test I quote is actually from a SAX handler for the <feed> element. I do various tests to make sure I get the version of atom. The assert is a post-condition to make sure that I've picked up at least something and I haven't managed to fall through a path that doesn't result in knowing the atom version.
Posted by JD at Fri Jun 2 09:49:03 2006
Or alternatively, Java could have non-broken == semantics, and you could write string == "string" (or the other way around if you prefer) and have that mean exactly the same thing as string.equals("string") except that null == "string" will return false rather than crashing.  Many languages have this sane == behavior, including Python, Ruby, and even C++.
Posted by Anonymous at Fri Jun 2 19:23:28 2006
Dear boyfriend,

Please to NOT let your blog spam my friends page again, ffs. 674920 of these boring-arse entries just appeared out of nowhere and ate up my f-list.

SORT IT OUT, KID.
Posted by Powny at Wed Jun 21 00:34:00 2006

Name:


E-mail:


URL:


Comment:


Please enter "fudge" to prove you are a human