intertwingly

It’s just data

First RadRails Patch


Last night I submitted my first patch to RadRails.  While RadRails looks promising, it wouldn’t work for me.  Based on some feedback I provided, a number of changes made it into the 0.3.1 release, but none of them quite fixed my problem.

The Problem

Trying to keep things simple, I used the default database adapter, i.e. mysql.  But no matter what I tried, I would run into the message that “RadRails could not connect to your database”.  At first I thought it might be the socket, as the socket you use to talk to mysql is in a different place in Ubuntu than on Mac OSX, and RadRails 0.3.0 did not permit one to specify the socket.

This was fixed in 0.3.1, making it obvious that the error was elsewhere.  But no feedback was provided to the user, and nothing was logged.

Being competent in Java, I embarked on loading up the latest sources and running it.  This was an adventure in itself, but I persisted.

Debugging went quickly: the problem occurred in this class.  And the error was as follows:

Host 'localhost.localdomain' is not allowed to connect to this MySQL server

What’s interesting about this is that I had specified localhost, and I had authorized localhost, not localhost.localdomain.  Apparently, somewhere in the bowels of either the MYSQL JDBC driver, or in JDBC itself, the hostname I provided was replaced with the result of reverse DNS look up.  In my case, the first name in the /etc/hosts file was picked up.  Here’s the relevant line from my /etc/hosts, unmodified from after the install of Ubuntu:

127.0.0.1 localhost.localdomain localhost rubypad

Sometimes abstractions can be too clever for their own good.

The Experience

I’ve programmed in Java for several years.  I’ve programmed in Ruby a couple of months.  And I must say that Eclipse is amazingly nimble on a 2Ghz Pentium with 2Gig of RAM.

Still, I’m taken aback by the productivity differences.  Ruby and Rails are open source, as are RadRails and Eclipse.  Given the state of the documentation in Rails, I have found it useful from time to time to peak into the implementation to figure out how to get things done.  Tool of choice: vim.

Similarly, in debugging the above problem, I stepped into both RadRails and Eclipse sources.  It has been a while since I used an IDE, but I still instinctively knew where to click to set a breakpoint, and while the function keys were different than the ones I used with that Microsoft debuggers in the past, the concepts of step into and step over were very familiar.

Despite all these “advantages”, I still found myself much more productive in Ruby and Rails, but I find it hard to point out specific reasons why.

For example: yes, Eclipse makes traversing from one class to another a breeze.  But I still spend way too much time stepping into getters and setters, trying to figure out how to step over others, and drilling down layer after layer of abstraction.  Abstractions in Rails tend not to be so smart - they don’t tend to do things like replace your host string with a canonical representation.  That’s a good thing.

Attempt at improvement

Another example: logging is a step forward, but in this case, the error message needs to be presented to the user.  I started to make the changes to get this message to bubble back through the layers of abstraction, but ultimately cheated and changed the logging class to retain the last message.  Static variables and their incumbent reentrancy issues be damned.

Ultimately, I got the right string to the right class, but it seems that with eclipse.jface you can present a MessageDialog with a openQuestion, or you can display a ErrorDialog with optional details.

No problem, I thought.  I’d just subclass ErrorDialog and add a cancel button.  It turns out that you can’t simply override createButtonsForButtonBar as there is no way to access the details button as it is private.

I could go on, but what troubles me is that none of these examples are conclusive.  Nothing in Java absolutely requires over-abstraction, but in practice, it happens all too much.  Java seems to encourage the notion of roles and sharp boundaries.  JDBC’s role is to abstract away the database, but it not only is “too smart”, but it also has no place for application specific features.  The inevitable result: people abstract away the abstraction (look at the last six directories).

In Ruby, classes generally can be viewed as starting points.

Conclusion

In the end, the only part of the patch I submitted was to log the message.