Friday, October 19, 2007

Driving Down the Developer Path

Sometimes, the world of a developer can seem overwhelming.  With so many choices at our disposal, there are a lot of questions that must be asked and answered.  Which web framework do I use?  Which design pattern is best suited for this problem?  Do I use Java or a dynamic scripting language?  How much test coverage is too much?  Too little?  What shortcuts are acceptable in order to meet deadlines?  Driving down the developer path sometimes reminds me of driving through Manhattan during rush hour on a Friday afternoon; if you're not alert and on your toes you just might find yourself in the middle of a 10 car pile-up.

But not everyone wants to drive in Manhattan during rush hour.  Some like the relaxed and picturesque drive on the roads of a quiet suburb outside of Denver, Colorado, with the convertible top down and the wind blowing through their hair.  Some like the straight lines of Florida roads, in their souped up Corvette, with their radar detector and the occasional opportunity to "let it breath!"  Some like the twists and turns of the Smoky Mountains, on two wheels, staring death right in the eyes at every turn as their knees scrape asphalt.  Some just have all the time in the world and are in no rush to get anywhere, oblivious of the other road patrons around them.

In many ways, software development is like driving.  The language we use, as with the vehicle we drive, is the tool we use to get from point A to point B.  Coupe, sedan, station wagon, minivan, motorcycle; Java, C#, C++, FORTRAN, Python, Perl.  A project that you work on is like taking a road trip.  The project plan and the AAA trip planner serve the function of laying out the optimum path to get you to your goal.  Once you start on your merry way, it's understood that the possibility exists that you will be confronted with some decisions to avoid undesirable situations.  A domain model change can be like an unannounced road construction.  A use-case change can be like a sudden downpour.

There are many analogies between driving to work in the morning and driving down the developer path.  And maybe, taking a moment to stop and think about those analogies will help one to understand what their goals are as a developer.  A vehicle will take you but so far before it's useful life has ended.  The same is true about the development tools you use.  Automobiles pretty much all work the same; you steer, you go and you stop.  Programming languages pretty much all work the same.  Syntax and semantics aside, they all fulfill the ultimate goal of dictating what the computer should do.  Where we fit into the picture is in coming up with paradigms and methodologies that best fit our character, goals, ambitions and dreams.

This is my (hopefully not so feeble) attempt in bringing about thought-provoking and stimulating ideas from the developer community.  What analogies have you been introduced to that helped you to "think outside the box?"  To drive you to "go that extra mile" and come up with some innovative idea that (and it needn't necessarily be an original idea in the community, but original to you) had you say to yourself, "why didn't I think of that before?"

Friday, October 12, 2007

Groovy Class Extension Gotcha

I've recently upgraded Groovy from 1.0-JSR-6 to 1.0 and started getting "No signature of method: static ... for argument types: ..." errors.  Upgrading further to version 1.1-beta3 exhibited the same behavior.  As an example, the following Groovy script will generate an error using Groovy version 1.0:

class S1 {
static String concat(String s, String c) {
  return s + c

class S2 extends S1 {
  static String concat(String s, Integer i) {
    return s + i

println "Calling S2.concat(String,Integer) ..."
println S2.concat('foo', 1)
def m = S2.getMethod('concat', [String, String] as Class[])
println "S2.concat(String,String)=${m}\n\nCalling S2.concat(String,String) ..."
println S2.concat('foo', '1')

After a bit of searching, I found a Groovy Jira issue which explains the Groovy behavior for static method calls on subclasses is that "a static method is callable only on the class it is defined on."  This means care must be taken to ensure subclass inherited static method calls are avoided in certain versions of Groovy.

A number of approaches to get around this are:

  1. If you can, upgrade to Groovy version 1.1-RC1 which allows inherited static method calls.
  2. Change all inherited static method calls to use the class in which the static method is declared.
  3. Change all inherited static method calls to use an instance method call.
  4. Modify the subclass to include static methods delegating to the superclass static methods.
  5. Use Groovy version 1.0-JSR-6.

Java developers are accustomed to subclasses inheriting static methods from their superclass.  So Groovy's behavior with static methods should not be overlooked as a Groovy gotcha.  I've tested this behavior in versions 1.0-JSR-6, 1.0 and 1.1-beta3. 

UPDATE: Moments after posting this blog, Groovy version 1.1-RC1 was released.  I tested version 1.1-RC1 today (2007/10/14) and have found the above snippet will work properly.  Looking at the groovy.lang.MetaClassImpl.invokeStaticMethod() code shows that static methods are now being searched for by traversing up the class hierarchy.