Monday, April 19, 2010

My wadings into the Ruby language

First of all, sorry for the lack of posts lately. I've been occupied with a number of things, one of them, a fast-track learning of Ruby, the topic of this post.

So having been at this web stuff for a while now, I have of course heard of Ruby. It first came to my awareness when Ruby on Rails was first making the rounds, about 5-6 years ago. I toyed with Rails a bit, and while I liked the concept, it didn't seem ready for the sorts of tasks I wanted, some of the layout bugged me, and I gave it a pass at the time. At that point I'd never really considered Ruby for non-web use. (IE: as a system scripting language.)

I had a similar stance on Java up until around that time, but it becoming so common, I started taking up that language. I was impressed that as of Java 1.5 it had really grown up, and in other ways, less impressed at how overgrown it had become.

Stay with me folks. This does come back to Ruby. :)

I really liked the more recent innovations in Java 1.6, including the JSR-232 specification that allowed for other language implementations on the Java Virtual Machine, and to varying degrees, interfacing back and forth between Java and the alternative language. There have since sprung a dizzying array of languages, from PHP, to Python, and yes Ruby. There are many more, both re-implementations of existing languages, and many new ones made to work closely with Java.

I ended up particularly drawn to one called Groovy, which supported all sorts of great things from a terse syntax befitting a scripting language, to powerful introspection and the ability to treat objects as transparent, mutable entities. This is totally alien to traditional Java programming, which is more like C++ in how it deals with the definition of objects (IE: resolved at compile time only). But it's right at home with scripting languages. Add to that that is was an alternate lanugage designed FOR the JVM, and had some of the best support for cross-implementation calls, and it was my favourite new language for a while.

Groovy also has something called Grails, which is something right along the lines of Ruby on Rails, but of course on Groovy, and more aligned to the various Java frameworks such as Spring, Hibernate, and JSP.

So with the back-story in place... how I've tripped into Ruby, is that similar to Java a few years ago, I am seeing there's a push of late to put it into place for serious development. So I have opened the door to learning it, and took a crash course with an O'Reilly book on the subject about two weeks ago. More on the book in a future post.

Overall it's been a great experience, Ruby has been very easy to work with and *almost* everything has just worked. It has most of what the Groovy language offers in terms of language features, but the commitment to Java becomes a choice, not a requirement. That said, the Java implementation of Ruby, jRuby is no slouch, and in some areas bests the original implementation, being first to offer things like pre-compilation of scripts. (Interestingly, both Groovy, and jRuby seem to originate from Codehaus)

While I can't talk any specifics about what I've been working on, I can say that I am amazed at how productive I've been with Ruby in this short time, having never gone beyond the "Hello World" example prior to a couple weeks ago.

Some various and random impressions:
  • It's not a simple language, it's nearly as grammaticly dense as Perl, but it feels like with less "edgy" cases. There's a simple simplicity and coherence to the language which reminds me of somewhat of Lua, in that even in the core language, higher-level details are often implemented in terms of lower-level language features. I am not sure it would be a good starter language for someone brand new to programming.
  • It's great as a system-level script language. Perl hacks will feel almost at home, and it rips off some things it would seem directly from perl (like magic punctuation variable names for various things, down to a "use english" variant). In fact, Ruby almost feels like Perl with a formal object specification. (And no, I don't count Moose, and never will... a rant for another day.)
  • It's great as a strong OO language. Java folks will feel almost right at home. While this may seem a direct contradiction to saying Perl folks will feel right at home, it oddly isn't. Ruby takes the everything-is-an-object approach to even deeper levels than Java. That said, there are adjustments for the Java programmer to make, such as some differing semantics on object/value equality, to exceptions being something your raise and rescue, instead of throwing and catching. (But you can still to the latter, which have nothing to do with exceptions in Ruby).
  • my intuition served me well in waiting for Ruby. I've already run into issues with slightly older versions of Ruby (any version below 1.8.7, the latest as I write this) and have seen readings around that strongly suggest that anything below that is likely to be problematic. Many are waiting with baited breath for the release of Ruby 1.9 which introduces some futher evolution to the language, but seems to be careful to be compatible to the 1.8.7 language specification. For the folks preferring not to use the jRuby implementation, this also brings big improvements in execution speed, and a proper bytecode/VM to make multiple execution more efficient. But all that said... 1.8.7 serves me quite well, and has been quite stable, both in the Java version and off.
  • the ecosystem for third party modules is strong, in a manner similar to Perl's CPAN. This is still my main reservation, as I don't consider it a good model for deployment for the installation instructions of my app have as it's first step be: "Install these dozen or so modules, and their dependencies, as extensions to your vendor's distribution of the language, from this ever-changing repository". How this ever came to be an acceptable request to make of someone deploying an application is utterly beyond me, and remains at the core of why languages such as Perl have fallen out of scope for many in my opinion. Even in my own endeavors with Perl, my strategy tended towards having projects bring in local versions of only pure-Perl modules, to be distributed with the application, to avoid having to ever emit such an insane set of installation notes.
So, I am taking the same cautious approach with Ruby, and so far, I have been getting fairly far using core or standard libraries. The problem is further compounded as I wish to create code which works equally well under either jRuby or the original, and the 3rd party modules, if not pure Ruby, are problematic to keep mobile between the two implementations.

If there's anything Java got right (and then got wrong again...) it was in putting an unrelenting focus on implementations in pure Java. If I need a MySQL driver, I grab it and go. If I need a serverlet container, I can grab it, and go... I need not concern myself with whether this particular system has the C client libraries, and the C compiler needed to install the driver to my language. (And that the version of my driver shim support my version of the language AND the version of my C driver, and... *head explodes*). All too often a language's support for this or that is a re-wrap of a C library, which makes it hard to deploy to N systems of varying specification.

I am hoping not to run into these frustrations too much with Ruby but will tread very carefully. I really like the language, and want to keep using it as a system-level scripting language. As well, in working with Grails, I came to accept the more rigid layouts that come with such frameworks, so I am looking forward to giving Rails another try soon too.

So there it is... that is one of many things distracting me from blogging. Hope to have more up soon. :)