This past weekend, I had some small digital housekeeping work to do involving some manipulations in a MySQL database. Mundane stuff: get records from database, perform some string manipulations, insert new records. Historically, my language of choice for this type of work has been Perl. Since it is now 2005, I guess that means that I have about 10 years of experience using Perl, so it’s fair to say that I can slice and dice with it pretty well. I don’t have to think too hard.
Since I had some spare time on my hands and because my last conversation with Pate about Ruby has been echoing in my head, I figured that it was about time to give it a whirl. A new language obviously has an associated ramp-up cost, but Ruby’s is pretty easy, especially if you’re fluent in both Perl and Java – it really felt like I was halfway between as I went about my little task.
I made it interesting by applying some of the patterns and more traditional OO stuff that I am accustomed to in order to see how they would fit in to the Ruby world, so it involved using the Ruby MySQL support, some of my own classes and a bunch of the built in classes that Ruby comes with.
Their module documentation is pretty good, but they also have a nice tutorial online that you can use to get your feet wet. Good documentation doesn’t mean having lots of documentation: it means having the right amount of well-written tutorials and reference guides that are easy to understand. My experience was pretty good in this regard.
Some of the nice rubyisms are nothing more than syntactic sugar… cute, but not necessary. Specifically, there are shortcut mechanisms for generating accessor and mutator methods (in Java, we call these getters and setters):
attr_reader :name, :artist, :duration
This creates getters on the Song class for the name, artist and duration fields. There are shortcuts for setters as well as both getters and setters.
Or this one, that iterates through a series of numbers from 0 to n:
for i in 0...@recurs.length
r = @recurs[i]
If you’re from the Kingdom of Perl, you already knew what this meant. But also kind of pythonesque, too, without semicolons at the end of each line.
Like I said: cute. But not going to make me switch.
More familiarity: Ruby’s begin/rescue/ensure syntax is similar to Java’s try/catch/finally construct, so it was easy to make sure my database connection was cleaned up properly if there was a problem executing. Syntactically, it just seemed like Perl without the ‘$’ char in front of scalar $variables.
Now, when you’re writing code, you need something to write it in. If I’m hacking Perl or just doing some quick job, then I’ll use emacs or vi. However, this is just an editor. My weapon of choice for my Java code is Eclipse. Let me clarify this, in case anybody has misunderstood my position on Eclipse: Eclipse is a Big Deal. Those who feel that you can productively write Java code using a text editor and javac are dreaming. It just ain’t so. Now, the cool thing about Eclipse is that it’s fairly generic and supports other languages (E-P-I-C provides Perl support, but I haven’t tried it). And, yes, there is support for Ruby… but it’s not great. You basically get syntax highlighting and the ability to run Ruby scripts right within Eclipse and watch the output on the console.
There’s no refactoring. There’s no autocomplete. There’s precious little in the way of parse errors, warnings or other guidance. I can’t walk the call hierarchy. I certainly can’t use FindBugs. Maybe someday there will be all of this, but it’s not there right now. Years ago, when I started doing more Java, I was sorely missing Perl’s CPAN. In case you don’t know, it’s a tool for managing your perl installation and performing module installations and also for discovering new modules. So if you’re working on a project and want to work with, say, sending email or something, you can use cpan to find and install modules that might be helpful to you. My affinity to CPAN pales in comparison to my affinity to Eclipse.
So while I can’t write Ruby code in Eclipse using all the bells and whistles, Ruby does have a CPAN analog called gems, which I didn’t use, but it was nice to see it.
Why did I say that Ruby has basically killed Perl? It’s because the Perl community has completely failed to articulate a way to build web applications. I guess I should count myself among those who have failed in this regard, because I didn’t come up anything either ðŸ˜‰ Yes, there’s mod_perl, but that’s just basically giving you the ability to write Apache modules in Perl instead of C. Want something more advanced? Well, Mason sits on top of mod_perl… so does Embperl and most of the other usable options. The problem with mod_perl is that it exists between whatever Apache is doing and whatever Perl is doing: it’s dependent on stability in both. Perl is in the process of a huge transition from Perl 5 to Perl 6. Apache successfully transitioned from 1.3 to 2.0, but mod_perl lagged behind for so long that people had plenty of time to consider all the potential threading problems that were going to occur. I’m not sure where that debate ended up. I tuned out.
The big buzz surrounding Ruby these days is Ruby on Rails; some people are making noise about the runtime performance as well as the ease with which web apps can be built. It’s conceptually similar to Struts and Hibernate, but it’s definitely nowhere near as mature. In any event, this is the Ruby community’s effort and it’s a great one. I wish the same could have been said for Perl.
In spite of all the Ruby joy that I’m spouting, I’m not yet convinced of Ruby’s place in enterprise or distributed environments yet. The only two current options in the enterprise space are .NET and J2EE. Sun did an absolutely horrible job describing Java to the world because they used the same word (Java) to describe three things: the platform, the language and the virtual machine. Microsoft was smarter about it, so they have .NET, C# and the CLR. Now, if you decide that C# or JavaTheLanguage aren’t your cup of tea, you can still write code in any language that compiles to bytecode or IL. Say, using Python. Or Scheme. I’m fairly sure that there’s no such ability in the Ruby world. And that’s a big deal. If you’re going to make a 15 year investment in a platform and commit hundreds of developers to it, you’re going to look for that level of flexibility and abstraction.
Furthermore, the big enterprise stuff doesn’t exist yet in Rubyland: distributed transactions with XA? Message queues with a unified interface? Concurrent programming libraries? The list here could go on and on.
Time will cure these shortcomings.
So Ruby’s good. I’m into it. My first experience was good, which means that I’ll certainly have a second experience.