Monday, June 25, 2007

Using Tricky Assertions

I'm not sure why, but I never got much in the habit of using the java assert keyword. Its a nice idea, but I somehow just checked what I wanted the old fashioned way.

And, although I'm a big fan of IDEs and I love debuggers, I still find having some print statements here and there sometimes is really helpful.

Of course, print statements suck when you're done and you no longer want them. That is, you need to go delete (or comment them out) all over the place.

I've sort of combined these ideas into a pretty obvious trick (which I seem to get asked about a fair bit, hence this post). Its basically a comment-out-less, performance-free debugging (or stats, or logging, or whatever) facility.

Simply:

assert(Debug.out("test code val="+val));
or
assert(Stat.increaseHitCount());

The only trick is that the method (like "Debug.out") must always return true. Now run the app with assertions turned on "java -ea Main" and you get the messages. For production, simply don't run with -ea and the VM will ignore those statements (I hope) altogether.

This basically gives you an application-wide, command-line way to turn on or off (with no performance hit if the VM is smart) some code. If you think about, there's many possible uses for such a thing.

Edit: Code for Debug.out would look something like:

class Debug {
 public static boolean out(String x) {
  System.out.println(x);
  return true;
 }
}

2 comments:

Albert said...

Neat idea, thanks for sharing. I was using sed scripts in my compiler script to replace all debug-related System.out.println statements up to today.

Martin said...

assert essentially gets compiled
to something like

private static final boolean
assertionsEnabled =
Boolean.getBoolean("some.system.property");

....

if (assertionsEnabled) { ... }

I think it would be clearer
to copy the implementation rather
than piggybacking on assert.
Get debugging output when invoking
your application with something
like
java -Dmyapp.debugLogging=true ...

Trust the JIT to do a reasonable
job optimizing away code guarded
by a static final boolean.