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.
on said:
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.
on said:
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.
on said:
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.
on said:
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++.
on said:
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.