Ruby Deeper Impressions

For two weeks (ending on this past Wednesday afternoon), most of my days and nights were occupied with a self-administered crash course in the Ruby programming language, outside of the Rails framework. I had struggled somewhat with Objective-C in January, partly because of the massive combined burden of learning the language, the Cocoa framework, the Xcode IDE, and the odd but brilliant Interface Builder. So, I wanted to try and attack Ruby in isolation.

Generally speaking, I like Ruby a lot. It is unnerving to work in an environment in which you can’t know if your code is remotely likely to work or not until you run those lines of code, but as I mentioned previously, thorough unit tests and a code coverage tool address that need.

I worked pretty hard to stylistically lean toward functional programming, and I think that worked pretty well. Whereas in Perl and Java I would have avoided the terse way of doing things in favor of clear (if lengthy) variable names and pseudocode in comments, in Ruby it seemed that in most cases, the extremely compact but algebraic way of doing things was equally readable and a lot simpler to understand.

Example:

Assuming you know what inject does (and it’s part of Array, so you really ought to if you know Ruby at all) and that you know that the application lets you configure it to ignore certain filesystems on each backed-up remote server, it’s pretty obvious what this method is telling you, and how it computes that.

I did find myself tugged back into the Java-ish way of thinking, which is to say that I still find static type checking and even a bit of Design by Contract to be comforting. Realizing that this might actually be a bad fit, though, I wrote a simple mixin module called ArgChecks that has a few methods like this:

You would call it (and its pals) like this:

I realized pretty quickly that the only place this was really necessary was right before I was about to do something where problems of nil-ness, wrong type, invalid range, wrong set of hash keys, etc. would actually cause something bad to happen, as opposed to checking if nil == firstname all the way down the call graph. That’s beyond defensive/paranoid programming, and well into OCD territory.

Still, even though I was arguably bringing some C++/Java baggage with me into Ruby land, Ruby allowed me to do it with a fair amount of elegance. My test classes were made elegant by another bit of Ruby goodness, using blocks:

That means I can do things like this in other tests:

Pretty tidy!

Really, the main complaint I have from my fortnight of Ruby development is that the Ruby Gems way of thinking doesn’t at all fit with the Debian/FHS way of thinking, so the package that Ubuntu installs for Ruby Gems kind of sucks, and it doesn’t really work correctly when you want the magic of “gem install xxx” to get some free code onto your system. I’m not sure if there’s anyone particularly at fault here, or if it’s just a philosophical rift that makes sense from both sides of the fence, but it’s inconvenient. On my to-do list for further Ruby work is an item called “reinstall Ruby Gems from source”.

Leave a Reply

Your email address will not be published. Required fields are marked *