So where was I? Ah yes, in yesterday’s post I left off with me going back to Ruby for my personal projects.
My standard choice for web development has been Ruby on Rails for a while now (although I haven’t had a chance to try Rails 2.0 yet). However, lately I’ve been playing with Merb. Merb is essentially a lightweight Rails replacement, originally built to address some specific (largely bloat and performance related) concerns. For Rails developers, Merb will seem quite familiar (at least superficially), as it uses the same application layout as Rails, with the usual directories for controllers and views, etc. But unlike Rails, the core framework is very lightweight, with additional functionality being provided by plugins. Unlike Rails’ slightly awkward plugin framework, Merb plugins are actually just standard Ruby gems that can be installed either as part of the Rails installation or inside the Merb application. In particular, Merb does not include an ORM framework for its model layer. There is a plugin that adds support for ActiveRecord, the ORM framework that Rails uses as well. But as an alternative, Merb also offers plugins for DataMapper and Sequel. And of course very simple applications might not need a database at all.
I am particularly interested in DataMapper, which offers several improvements over ActiveRecord. Most importantly, it is thread-safe. But it also moves the definition of a model’s properties from the database into the Ruby class. The fact that ActiveRecord infers all attributes from the database has always seemed slightly unnatural to me, so moving the definition into Ruby code makes more sense to me. I do however miss ActiveRecord’s support for migrations (anyone remember when ActiveRecord did not have this feature yet and how big a difference it made when it was released?).
One thing I should mention is that Merb is currently undergoing a major transformation. The 0.5 version (which the Merb website still refers to) has been end-of-lifed (0.5.3 was the final release), and development has shifted to the 0.9 version. 0.9 takes an even more radical approach: The existing Merb gem will be split into merb-core (the actual core, very lightweight), merb-more (support for generators, mailers, the Haml template language, etc.), and merb-plugins (things like ORM framework support). Merb is also adopting the Rack interface, which is becoming the standard way for Ruby web applications to plug into any compatible web servers (similar to Python’s WSGI).
The 0.9 release is expected to come out any day now, and you can follow its development on github (Merb shifted from Subversion to Git) and the Lighthouse bug tracker. If you want to get more involved with Merb, Michael Ivey wrote an interesting two-part article on contributing to Merb (and part two). There is also a pretty active and helpful community on IRC (#merb on Freenode). Merb was originally implemented by Ezra Zygmuntowicz, who founded the Engine Yard hosting service, and with the recent investment into Engine Yard, Merb (as well as other Engine Yard supported apps such as Rubinius) now has several dedicated developers working on it and seems to have a bright future.
Right now I am using Merb to build a simple Facebook application. I’ll blog more about this later, but so far it seems like a good choice for this type of application. The transition from Rails is relatively easy (although this is likely more complicated if you are relying on a lot of the Rails magic such as the various helper classes), and the Merb community is very helpful. Deploying a Merb app is not much different from deploying a Rails app. I am currently deploying my Merb app-in-progress via Capistrano to SliceHost and running on Nginx and Mongrel (mainly following these instructions).
In my current application, I am also giving Haml a shot for the first time. It takes some getting used to (after being indoctrinated with HTML for over a decade…), but you quickly learn to appreciate its elegance and conciseness (it really makes you realize how much redundancy HTML carries around).
One thing I haven’t tried yet is RSpec (so far I’ve been using good old-fashioned Test::Unit), but the trend seems to go towards RSpec, so I’ll have to check it out one of these days. It’s amazing how quickly these technologies shift in the very dynamic Ruby world, and sometimes quite hard to keep up when I’m only using it occasionally in my spare time…