Oct 272006

I’m been doing some work in Ruby to build a parser framework and I wanted to have pluggable parsers from the command line. I figured this would be simple because in Java it actually is pretty simple, as long as the pluggable parser is in the classpath. Well, with Ruby, this isn’t quite the case. Even if a class is in the load path, it still isn’t visible until it has been loaded either via the load method or the require method on Kernel. This is annoying and something I wasn’t used to. But a quick hackery fixes this nicely:

This loads every *.rb file in the current directory into the current Ruby process. Then you can do some String reflection magic to load a class:

This allows me to call my scriptage and pass in the prefix of the class name like this:

This will then instantiate an instance of MySpecialParser. I could have iterated over all the constants in the entire Ruby process and found the symbol I needed and then called new on that, but that sucks. Eval is much cleaner in this case.

In fact, in Java loading a class by name is simple:

In Ruby this doesn’t work so well. You have to first load all the .rb files like I did and then use eval. They really should add something to Class or ObjectSpace or Kernel to do all this for you. In fact, I think in 2.0 load_path should be able to load all files in the load path via reflection without any requires or load crapola.

Oct 252006

Okay, I’ve been doing a lot of research on SOA and distribution lately for some material I’m putting together for Platinum Solutions and I ran into a post by Craig McMurthy about Indigo vs. Jini. This one is pretty old, but I noticed that Craig was pretty much way off based except for one part. I won’t get into that, but I was considering leaving s comment. Well, turns out Craig couldn’t take the heat (I’m assuming) of his unresearched post, incorrect and misleading statements and turned comments off.

So, here’s my warning to everyone, if you see a post that doesn’t allow comments, just skip it, it’s probably flame-bait or completely incorrect. And to bloggers, leave comments on. It’s the only way to validate yourself with millions of blogs and hordes of information flying about.

Oct 042006

I’ve been working with the writers of a popular framework lately on some issues with a release. One of the things we ran into was that the semantics of a method changed with the new release and this in turn made our application stop working. This got me to thinking about APIs in general. It brought me back to the first time I read “How to Design a Good API and Why it Matters,” by Joshua Bloch. This presentation goes over a lot of the design strategies around public APIs and one slide in particular put into words something I have been doing for a long time, “Public APIs are forever – one chance to get it right”. This is also followed up a few slides later with, “When in doubt leave it out”.

Why is this so important in API design? Because if you provide a class or a method, people will use it AND they will expect it to always work the same way no matter how many versions you go through. The only chance you ever have of removing or changing a method is when you do a “ball-buster” release.

This issue came up on this framework I’ve been working with (I’m leaving names out intentionally). I was using an API call to do a bit of work that otherwise was quite difficult and cumbersome. This API call removed a lot of code and made things much faster to develop. We actually found the API by doing a bit of Googling, which means that many others are using this API as well. During the latest release of said framework this API call stopped working as it had before and how its documentation stated. After a submitting a bug and a little discussion I was informed that I should refactor everything and do it the long way (well of course that will work but I used the API method because that way sucks) and :

(The API calls) are supposed to be a last-resort fallback only (snip). We just don’t recommend (them) for such needs in the first place.

I went back and looked at the JavaDoc and of course down at the bottom of the class comment it said:

However, this approach should not be used when there is a reasonable alternative.

This is not a good API design. You can document public API classes and methods telling people not to use them until your hands fall off, but guess what, people are going to use them if it makes life simpler or there is no other way. Additionally, you can’t tell someone who has been using an API that you made public that you don’t want to support it. You’re the one who opened the API up and therefore you took on all responsibilities in maintenance. Therefore, my rule of thumb is, don’t open things to the public if you:

  • Don’t want to support it
  • Don’t think it should be used

This is the same reason that deprecated is pretty much a worthless concept overall. Unless you have control over all the code that compiles against a deprecated method, you can’t expect people to stop using it because it costs money and usually a lot of it, to go back and change code. Deprecation usually says to me, “oops my bad!”. The only help that deprecation provides is getting folks ready for “ball-buster” releases. I won’t get into those things, but let’s just say that most well known APIs don’t ever do them.

If you intend to write a public API, realize up front what you are doing and don’t assume things about your users. Stay away from deprecation and understand what maintenance really means. So, go forth and design good APIs.